]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6 into lvs-next-2.6
authorSimon Horman <horms@verge.net.au>
Mon, 6 Oct 2008 21:40:11 +0000 (08:40 +1100)
committerSimon Horman <horms@verge.net.au>
Mon, 6 Oct 2008 21:40:11 +0000 (08:40 +1100)
636 files changed:
.mailmap
Documentation/ABI/testing/sysfs-gpio [new file with mode: 0644]
Documentation/DMA-mapping.txt
Documentation/cpusets.txt
Documentation/feature-removal-schedule.txt
Documentation/filesystems/Locking
Documentation/filesystems/proc.txt
Documentation/ioctl/cdrom.txt
Documentation/networking/can.txt
Documentation/networking/phonet.txt [new file with mode: 0644]
Documentation/sysctl/kernel.txt
Documentation/usb/anchors.txt
MAINTAINERS
Makefile
arch/arm/include/asm/pci.h
arch/arm/kernel/kgdb.c
arch/arm/mach-davinci/psc.c
arch/arm/mach-kirkwood/db88f6281-bp-setup.c
arch/arm/mach-kirkwood/rd88f6192-nas-setup.c
arch/arm/mach-kirkwood/rd88f6281-setup.c
arch/arm/mach-loki/lb88rc8480-setup.c
arch/arm/mach-mv78xx0/common.c
arch/arm/mach-mv78xx0/db78x00-bp-setup.c
arch/arm/mach-mx3/pcm037.c
arch/arm/mach-orion5x/db88f5281-setup.c
arch/arm/mach-orion5x/dns323-setup.c
arch/arm/mach-orion5x/kurobox_pro-setup.c
arch/arm/mach-orion5x/mss2-setup.c
arch/arm/mach-orion5x/mv2120-setup.c
arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
arch/arm/mach-orion5x/rd88f5182-setup.c
arch/arm/mach-orion5x/ts78xx-setup.c
arch/arm/mach-orion5x/tsx09-common.c
arch/arm/mach-orion5x/wnr854t-setup.c
arch/arm/mach-orion5x/wrt350n-v2-setup.c
arch/arm/mach-pxa/time.c
arch/arm/mach-pxa/tosa.c
arch/arm/mach-sa1100/generic.c
arch/arm/mach-sa1100/include/mach/jornada720.h
arch/arm/mach-sa1100/jornada720_ssp.c
arch/arm/mach-versatile/core.c
arch/arm/plat-omap/devices.c
arch/avr32/boards/atstk1000/atstk1002.c
arch/avr32/boot/images/.gitignore [new file with mode: 0644]
arch/avr32/kernel/.gitignore [new file with mode: 0644]
arch/avr32/kernel/avr32_ksyms.c
arch/avr32/kernel/syscall-stubs.S
arch/avr32/kernel/syscall_table.S
arch/avr32/kernel/traps.c
arch/avr32/lib/findbit.S
arch/ia64/include/asm/elf.h
arch/ia64/include/asm/sections.h
arch/ia64/include/asm/sn/bte.h
arch/ia64/kernel/efi.c
arch/ia64/kernel/module.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/smpboot.c
arch/ia64/kvm/kvm-ia64.c
arch/ia64/sn/pci/tioca_provider.c
arch/m32r/Kconfig
arch/m32r/kernel/entry.S
arch/m32r/kernel/head.S
arch/m32r/kernel/irq.c
arch/m32r/kernel/m32r_ksyms.c
arch/m32r/kernel/process.c
arch/m32r/kernel/smp.c
arch/m32r/kernel/time.c
arch/m32r/kernel/traps.c
arch/m32r/lib/delay.c
arch/m68k/configs/amiga_defconfig
arch/m68k/configs/apollo_defconfig
arch/m68k/configs/atari_defconfig
arch/m68k/configs/bvme6000_defconfig
arch/m68k/configs/hp300_defconfig
arch/m68k/configs/mac_defconfig
arch/m68k/configs/multi_defconfig
arch/m68k/configs/mvme147_defconfig
arch/m68k/configs/mvme16x_defconfig
arch/m68k/configs/q40_defconfig
arch/m68k/configs/sun3_defconfig
arch/m68k/configs/sun3x_defconfig
arch/mips/au1000/common/gpio.c
arch/mips/kernel/cpu-probe.c
arch/mips/kernel/genex.S
arch/mips/kernel/kgdb.c
arch/mips/kernel/process.c
arch/mips/kernel/traps.c
arch/mips/kernel/vmlinux.lds.S
arch/mips/lib/csum_partial.S
arch/mips/pci/Makefile
arch/mips/pci/pci-bcm47xx.c [new file with mode: 0644]
arch/mips/pci/pci-ip27.c
arch/mips/sgi-ip22/ip22-platform.c
arch/mips/vr41xx/common/irq.c
arch/mn10300/kernel/time.c
arch/mn10300/mm/fault.c
arch/parisc/kernel/module.c
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/include/asm/elf.h
arch/powerpc/include/asm/sections.h
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/module_64.c
arch/powerpc/sysdev/mv64x60_dev.c
arch/s390/kernel/compat_ptrace.h
arch/s390/kernel/ptrace.c
arch/sparc/kernel/of_device.c
arch/sparc/kernel/ptrace.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/pci_psycho.c
arch/sparc64/kernel/prom.c
arch/sparc64/kernel/ptrace.c
arch/sparc64/kernel/traps.c
arch/x86/Kconfig.cpu
arch/x86/kernel/amd_iommu.c
arch/x86/kernel/apm_32.c
arch/x86/kernel/cpu/common.c
arch/x86/kernel/e820.c
arch/x86/kernel/kdebugfs.c
arch/x86/kernel/kgdb.c
arch/x86/kernel/process.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/setup.c
arch/x86/kernel/vsmp_64.c
arch/x86/kvm/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/vmx.c
arch/x86/kvm/vmx.h
arch/x86/mm/init_32.c
arch/x86/oprofile/nmi_int.c
arch/x86/xen/setup.c
block/cmd-filter.c
drivers/ata/ata_piix.c
drivers/ata/sata_inic162x.c
drivers/ata/sata_nv.c
drivers/atm/eni.c
drivers/atm/horizon.c
drivers/atm/idt77252.c
drivers/atm/idt77252.h
drivers/atm/zatm.c
drivers/block/aoe/aoe.h
drivers/block/aoe/aoeblk.c
drivers/block/aoe/aoechr.c
drivers/block/aoe/aoecmd.c
drivers/block/aoe/aoedev.c
drivers/block/aoe/aoemain.c
drivers/block/aoe/aoenet.c
drivers/bluetooth/btusb.c
drivers/bluetooth/hci_bcsp.c
drivers/bluetooth/hci_usb.h
drivers/char/tty_io.c
drivers/clocksource/acpi_pm.c
drivers/crypto/talitos.c
drivers/hwmon/ad7414.c
drivers/hwmon/atxp1.c
drivers/hwmon/it87.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/i2c-dev.c
drivers/ide/Kconfig
drivers/ide/ide-cd.c
drivers/ide/ide-tape.c
drivers/ide/mips/swarm.c
drivers/ide/pci/hpt366.c
drivers/infiniband/hw/mlx4/qp.c
drivers/infiniband/hw/nes/nes_cm.c
drivers/infiniband/ulp/ipoib/ipoib.h
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/input/mouse/bcm5974.c
drivers/input/touchscreen/jornada720_ts.c
drivers/isdn/capi/kcapi.c
drivers/isdn/hardware/mISDN/hfc_pci.h
drivers/isdn/hardware/mISDN/hfcpci.c
drivers/isdn/i4l/isdn_ppp.c
drivers/isdn/mISDN/timerdev.c
drivers/md/md.c
drivers/media/video/Kconfig
drivers/memstick/core/memstick.c
drivers/memstick/core/mspro_block.c
drivers/memstick/host/jmb38x_ms.c
drivers/misc/sgi-gru/grufile.c
drivers/mmc/card/block.c
drivers/mmc/card/mmc_test.c
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/tmio_mmc.h
drivers/net/3c505.c
drivers/net/8139too.c
drivers/net/Kconfig
drivers/net/arcnet/arcnet.c
drivers/net/arcnet/com20020.c
drivers/net/atl1e/atl1e_hw.c
drivers/net/atl1e/atl1e_main.c
drivers/net/atlx/atl2.c
drivers/net/au1000_eth.c
drivers/net/ax88796.c
drivers/net/bfin_mac.c
drivers/net/bnx2.h
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/cassini.c
drivers/net/cassini.h
drivers/net/cs89x0.c
drivers/net/cxgb3/adapter.h
drivers/net/cxgb3/cxgb3_offload.c
drivers/net/cxgb3/l2t.c
drivers/net/cxgb3/l2t.h
drivers/net/cxgb3/sge.c
drivers/net/e100.c
drivers/net/e1000/e1000.h
drivers/net/e1000/e1000_hw.c
drivers/net/e1000/e1000_main.c
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/netdev.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_phyp.c
drivers/net/ehea/ehea_qmr.c
drivers/net/enc28j60.c
drivers/net/enic/enic.h
drivers/net/enic/enic_main.c
drivers/net/forcedeth.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/fs_enet/fs_enet.h
drivers/net/fs_enet/mac-fcc.c
drivers/net/fs_enet/mac-fec.c
drivers/net/fs_enet/mac-scc.c
drivers/net/gianfar_mii.c
drivers/net/hp-plus.c
drivers/net/ibm_newemac/Kconfig
drivers/net/ibm_newemac/phy.c
drivers/net/irda/vlsi_ir.c
drivers/net/ixgb/ixgb.h
drivers/net/ixgbe/ixgbe.h
drivers/net/ixgbe/ixgbe_82598.c
drivers/net/ixgbe/ixgbe_common.c
drivers/net/ixgbe/ixgbe_common.h
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_phy.c
drivers/net/ixgbe/ixgbe_phy.h
drivers/net/ixgbe/ixgbe_type.h
drivers/net/meth.c
drivers/net/mipsnet.c
drivers/net/mlx4/alloc.c
drivers/net/mlx4/mr.c
drivers/net/mv643xx_eth.c
drivers/net/myri10ge/myri10ge.c
drivers/net/myri_sbus.c
drivers/net/ne.c
drivers/net/netx-eth.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_main.c
drivers/net/niu.c
drivers/net/pci-skeleton.c
drivers/net/phy/mdio_bus.c
drivers/net/ppp_generic.c
drivers/net/pppol2tp.c
drivers/net/r6040.c
drivers/net/r8169.c
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/sb1250-mac.c
drivers/net/sfc/efx.c
drivers/net/sfc/falcon.c
drivers/net/sfc/falcon.h
drivers/net/sfc/falcon_hwdefs.h
drivers/net/sfc/falcon_io.h
drivers/net/sfc/falcon_xmac.c
drivers/net/sfc/net_driver.h
drivers/net/sfc/sfe4001.c
drivers/net/sfc/tenxpress.c
drivers/net/sfc/tx.c
drivers/net/sfc/workarounds.h
drivers/net/sfc/xfp_phy.c
drivers/net/skfp/pmf.c
drivers/net/smc911x.c
drivers/net/smc91x.c
drivers/net/smc91x.h
drivers/net/sunbmac.c
drivers/net/sundance.c
drivers/net/tehuti.h
drivers/net/tsi108_eth.c
drivers/net/tulip/de2104x.c
drivers/net/tulip/de4x5.c
drivers/net/ucc_geth.c
drivers/net/usb/hso.c
drivers/net/usb/mcs7830.c
drivers/net/usb/pegasus.c
drivers/net/usb/usbnet.c
drivers/net/via-velocity.h
drivers/net/wan/cycx_drv.c
drivers/net/wan/cycx_x25.c
drivers/net/wan/dscc4.c
drivers/net/wan/hdlc_x25.c
drivers/net/wan/pc300_tty.c
drivers/net/wan/sbni.c
drivers/net/wireless/airo.c
drivers/net/wireless/airo_cs.c
drivers/net/wireless/ath5k/ath5k.h
drivers/net/wireless/ath5k/attach.c
drivers/net/wireless/ath5k/base.c
drivers/net/wireless/ath5k/dma.c
drivers/net/wireless/ath5k/pcu.c
drivers/net/wireless/ath5k/phy.c
drivers/net/wireless/ath5k/qcu.c
drivers/net/wireless/ath5k/reg.h
drivers/net/wireless/ath5k/reset.c
drivers/net/wireless/ath9k/beacon.c
drivers/net/wireless/ath9k/core.c
drivers/net/wireless/ath9k/core.h
drivers/net/wireless/ath9k/hw.c
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/ath9k/rc.c
drivers/net/wireless/ath9k/xmit.c
drivers/net/wireless/atmel.c
drivers/net/wireless/atmel_cs.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/rfkill.c
drivers/net/wireless/b43legacy/rfkill.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.h
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-csr.h
drivers/net/wireless/iwlwifi/iwl-fh.h
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/cmd.h
drivers/net/wireless/libertas/defs.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/wext.c
drivers/net/wireless/netwave_cs.c
drivers/net/wireless/orinoco.c
drivers/net/wireless/orinoco_cs.c
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/p54/p54common.h
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/spectrum_cs.c
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_usb.c
drivers/pci/hotplug/fakephp.c
drivers/pci/hotplug/pciehp_hpc.c
drivers/pci/intel-iommu.c
drivers/pci/pcie/aspm.c
drivers/pci/probe.c
drivers/pci/search.c
drivers/pci/setup-bus.c
drivers/pcmcia/ds.c
drivers/pcmcia/soc_common.c
drivers/s390/cio/ccwgroup.c
drivers/s390/cio/chp.c
drivers/s390/cio/cio.c
drivers/s390/cio/css.c
drivers/s390/cio/device_fsm.c
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c
drivers/s390/scsi/zfcp_ccw.c
drivers/s390/scsi/zfcp_fc.c
drivers/s390/scsi/zfcp_fsf.c
drivers/s390/scsi/zfcp_qdio.c
drivers/scsi/Kconfig
drivers/scsi/device_handler/scsi_dh_alua.c
drivers/scsi/device_handler/scsi_dh_emc.c
drivers/scsi/device_handler/scsi_dh_rdac.c
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/qla2xxx/qla_os.c
drivers/scsi/qlogicpti.c
drivers/scsi/scsi_error.c
drivers/scsi/scsi_lib.c
drivers/scsi/scsi_scan.c
drivers/scsi/sd.c
drivers/scsi/sr.c
drivers/serial/atmel_serial.c
drivers/serial/imx.c
drivers/spi/pxa2xx_spi.c
drivers/spi/spi_mpc83xx.c
drivers/spi/spi_s3c24xx.c
drivers/ssb/main.c
drivers/usb/atm/usbatm.c
drivers/usb/core/hcd.c
drivers/usb/core/hub.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/omap_udc.c
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci-sched.c
drivers/usb/musb/Kconfig
drivers/usb/musb/musb_core.c
drivers/usb/musb/omap2430.c
drivers/usb/musb/omap2430.h
drivers/usb/serial/cp2101.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/option.c
drivers/usb/serial/sierra.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/Kconfig
drivers/usb/storage/Makefile
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/video/atmel_lcdfb.c
drivers/watchdog/geodewdt.c
drivers/watchdog/ibmasr.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/rc32434_wdt.c
drivers/watchdog/rdc321x_wdt.c
drivers/watchdog/wdt285.c
drivers/xen/balloon.c
firmware/Makefile
firmware/WHENCE
firmware/sun/cassini.bin.ihex [new file with mode: 0644]
fs/9p/vfs_inode.c
fs/bfs/dir.c
fs/dcache.c
fs/exec.c
fs/ocfs2/aops.c
fs/partitions/check.c
fs/proc/generic.c
fs/proc/proc_misc.c
fs/ubifs/budget.c
fs/ubifs/debug.c
fs/ubifs/dir.c
fs/ubifs/file.c
fs/ubifs/find.c
fs/ubifs/gc.c
fs/ubifs/misc.h
fs/ubifs/super.c
fs/ubifs/tnc.c
fs/ubifs/ubifs-media.h
fs/ubifs/ubifs.h
fs/udf/file.c
fs/udf/ialloc.c
fs/xfs/linux-2.6/xfs_aops.c
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_dfrag.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_log.c
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_vnodeops.c
include/asm-generic/sections.h
include/asm-mips/pgtable-32.h
include/asm-parisc/sections.h
include/asm-x86/acpi.h
include/asm-x86/cpufeature.h
include/asm-x86/idle.h
include/asm-x86/kgdb.h
include/linux/Kbuild
include/linux/ata.h
include/linux/blkdev.h
include/linux/cnt32_to_63.h [moved from arch/arm/include/asm/cnt32_to_63.h with 87% similarity]
include/linux/ieee80211.h
include/linux/if.h
include/linux/if_ether.h
include/linux/if_link.h
include/linux/if_phonet.h [new file with mode: 0644]
include/linux/in.h
include/linux/ioport.h
include/linux/isdn_ppp.h
include/linux/memstick.h
include/linux/mlx4/device.h
include/linux/mmzone.h
include/linux/mv643xx_eth.h
include/linux/netdevice.h
include/linux/pci.h
include/linux/pci_ids.h
include/linux/pfkeyv2.h
include/linux/phonet.h [new file with mode: 0644]
include/linux/phy.h
include/linux/pnp.h
include/linux/rtnetlink.h
include/linux/skbuff.h
include/linux/smb.h
include/linux/socket.h
include/linux/xfrm.h
include/net/9p/9p.h
include/net/9p/transport.h
include/net/cfg80211.h
include/net/flow.h
include/net/ieee80211.h
include/net/inet_sock.h
include/net/inet_timewait_sock.h
include/net/ip.h
include/net/ip_vs.h
include/net/ipv6.h
include/net/mac80211.h
include/net/netlink.h
include/net/phonet/gprs.h [new file with mode: 0644]
include/net/phonet/pep.h [new file with mode: 0644]
include/net/phonet/phonet.h [new file with mode: 0644]
include/net/phonet/pn_dev.h [new file with mode: 0644]
include/net/pkt_sched.h
include/net/route.h
include/net/sch_generic.h
include/net/sctp/sctp.h
include/net/sctp/sm.h
include/net/sctp/structs.h
include/net/tcp.h
include/net/udp.h
include/net/wireless.h
include/net/xfrm.h
include/scsi/scsi.h
kernel/cgroup.c
kernel/cpuset.c
kernel/exit.c
kernel/kexec.c
kernel/kgdb.c
kernel/sched.c
kernel/sched_rt.c
kernel/time/clockevents.c
kernel/time/tick-broadcast.c
kernel/time/tick-common.c
kernel/time/tick-internal.h
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
lib/scatterlist.c
lib/swiotlb.c
lib/vsprintf.c
mm/memcontrol.c
mm/mmzone.c
mm/slub.c
mm/tiny-shmem.c
net/9p/client.c
net/9p/conv.c
net/9p/mod.c
net/9p/trans_fd.c
net/9p/trans_virtio.c
net/Kconfig
net/Makefile
net/atm/lec.c
net/bluetooth/hci_core.c
net/core/dev.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/ipv4/af_inet.c
net/ipv4/inet_connection_sock.c
net/ipv4/inet_timewait_sock.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/netfilter.c
net/ipv4/netfilter/nf_nat_helper.c
net/ipv4/route.c
net/ipv4/syncookies.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv6/af_inet6.c
net/ipv6/netfilter/ip6t_hbh.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/tcp_ipv6.c
net/iucv/iucv.c
net/key/af_key.c
net/mac80211/cfg.c
net/mac80211/debugfs_sta.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_pathtbl.c
net/mac80211/mlme.c
net/mac80211/rate.c
net/mac80211/rate.h
net/mac80211/rc80211_pid.h
net/mac80211/rc80211_pid_algo.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/tx.c
net/mac80211/wme.c
net/netfilter/xt_time.c
net/phonet/Kconfig [new file with mode: 0644]
net/phonet/Makefile [new file with mode: 0644]
net/phonet/af_phonet.c [new file with mode: 0644]
net/phonet/datagram.c [new file with mode: 0644]
net/phonet/pep-gprs.c [new file with mode: 0644]
net/phonet/pep.c [new file with mode: 0644]
net/phonet/pn_dev.c [new file with mode: 0644]
net/phonet/pn_netlink.c [new file with mode: 0644]
net/phonet/socket.c [new file with mode: 0644]
net/phonet/sysctl.c [new file with mode: 0644]
net/sched/em_cmp.c
net/sched/sch_generic.c
net/sctp/associola.c
net/sctp/bind_addr.c
net/sctp/ipv6.c
net/sctp/output.c
net/sctp/outqueue.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/sm_statetable.c
net/sctp/socket.c
net/sctp/ulpqueue.c
net/socket.c
net/wireless/core.c
net/wireless/nl80211.c
net/wireless/reg.c
net/wireless/reg.h
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
scripts/kconfig/conf.c
scripts/kconfig/confdata.c
scripts/kernel-doc
sound/core/pcm.c
sound/core/pcm_native.c
sound/core/rawmidi.c
sound/soc/at32/at32-pcm.c
sound/soc/codecs/cs4270.c

index 726084286d33e626ddc2bf69db078cdc972c0e4e..dfab12f809ed9c678638844ced3717742986ab26 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -96,4 +96,6 @@ Tejun Heo <htejun@gmail.com>
 Thomas Graf <tgraf@suug.ch>
 Tony Luck <tony.luck@intel.com>
 Tsuneo Yoshioka <Tsuneo.Yoshioka@f-secure.com>
+Uwe Kleine-König <Uwe.Kleine-Koenig@digi.com>
+Uwe Kleine-König <ukleinek@informatik.uni-freiburg.de>
 Valdis Kletnieks <Valdis.Kletnieks@vt.edu>
diff --git a/Documentation/ABI/testing/sysfs-gpio b/Documentation/ABI/testing/sysfs-gpio
new file mode 100644 (file)
index 0000000..8aab809
--- /dev/null
@@ -0,0 +1,26 @@
+What:          /sys/class/gpio/
+Date:          July 2008
+KernelVersion: 2.6.27
+Contact:       David Brownell <dbrownell@users.sourceforge.net>
+Description:
+
+  As a Kconfig option, individual GPIO signals may be accessed from
+  userspace.  GPIOs are only made available to userspace by an explicit
+  "export" operation.  If a given GPIO is not claimed for use by
+  kernel code, it may be exported by userspace (and unexported later).
+  Kernel code may export it for complete or partial access.
+
+  GPIOs are identified as they are inside the kernel, using integers in
+  the range 0..INT_MAX.  See Documentation/gpio.txt for more information.
+
+    /sys/class/gpio
+       /export ... asks the kernel to export a GPIO to userspace
+       /unexport ... to return a GPIO to the kernel
+       /gpioN ... for each exported GPIO #N
+           /value ... always readable, writes fail for input GPIOs
+           /direction ... r/w as: in, out (default low); write: high, low
+       /gpiochipN ... for each gpiochip; #N is its first GPIO
+           /base ... (r/o) same as N
+           /label ... (r/o) descriptive, not necessarily unique
+           /ngpio ... (r/o) number of GPIOs; numbered N to N + (ngpio - 1)
+
index b463ecd0c7cebf36f53104015afcbeeccf4b934d..c74fec8c2351168d1329c527183f3a975234030e 100644 (file)
@@ -740,7 +740,7 @@ failure can be determined by:
        dma_addr_t dma_handle;
 
        dma_handle = pci_map_single(pdev, addr, size, direction);
-       if (pci_dma_mapping_error(dma_handle)) {
+       if (pci_dma_mapping_error(pdev, dma_handle)) {
                /*
                 * reduce current DMA mapping usage,
                 * delay and try again later or
index 1f5a924d1e56430bc3c8a0a6bb74e7524fab1670..47e568a9370afa28f703acf9ce55f88a8ca52519 100644 (file)
@@ -635,14 +635,16 @@ prior 'mems' setting, will not be moved.
 
 There is an exception to the above.  If hotplug functionality is used
 to remove all the CPUs that are currently assigned to a cpuset,
-then the kernel will automatically update the cpus_allowed of all
-tasks attached to CPUs in that cpuset to allow all CPUs.  When memory
-hotplug functionality for removing Memory Nodes is available, a
-similar exception is expected to apply there as well.  In general,
-the kernel prefers to violate cpuset placement, over starving a task
-that has had all its allowed CPUs or Memory Nodes taken offline.  User
-code should reconfigure cpusets to only refer to online CPUs and Memory
-Nodes when using hotplug to add or remove such resources.
+then all the tasks in that cpuset will be moved to the nearest ancestor
+with non-empty cpus.  But the moving of some (or all) tasks might fail if
+cpuset is bound with another cgroup subsystem which has some restrictions
+on task attaching.  In this failing case, those tasks will stay
+in the original cpuset, and the kernel will automatically update
+their cpus_allowed to allow all online CPUs.  When memory hotplug
+functionality for removing Memory Nodes is available, a similar exception
+is expected to apply there as well.  In general, the kernel prefers to
+violate cpuset placement, over starving a task that has had all
+its allowed CPUs or Memory Nodes taken offline.
 
 There is a second exception to the above.  GFP_ATOMIC requests are
 kernel internal allocations that must be satisfied, immediately.
index c93fcdec246d9f9f36da53a53da383a54020b382..d0f22fac55daf4c3af9a23ab4ff7135b18b8b3b4 100644 (file)
@@ -340,3 +340,11 @@ Why:  Accounting can now be enabled/disabled without kernel recompilation.
       controlled by a kernel/module/sysfs/sysctl parameter.
 Who:  Krzysztof Piotr Oledzki <ole@ans.pl>
 
+---------------------------
+
+What: ide-scsi (BLK_DEV_IDESCSI)
+When: 2.6.29
+Why:  The 2.6 kernel supports direct writing to ide CD drives, which
+      eliminates the need for ide-scsi. The new method is more
+      efficient in every way.
+Who:  FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
index 680fb566b9286bcc71a527c5f75d4b94fc9ac215..8362860e21a7d6b4db3595e83905b32b25e55ecf 100644 (file)
@@ -144,8 +144,8 @@ prototypes:
        void (*kill_sb) (struct super_block *);
 locking rules:
                may block       BKL
-get_sb         yes             yes
-kill_sb                yes             yes
+get_sb         yes             no
+kill_sb                yes             no
 
 ->get_sb() returns error or 0 with locked superblock attached to the vfsmount
 (exclusive on ->s_umount).
@@ -409,12 +409,12 @@ ioctl:                    yes     (see below)
 unlocked_ioctl:                no      (see below)
 compat_ioctl:          no
 mmap:                  no
-open:                  maybe   (see below)
+open:                  no
 flush:                 no
 release:               no
 fsync:                 no      (see below)
 aio_fsync:             no
-fasync:                        yes     (see below)
+fasync:                        no
 lock:                  yes
 readv:                 no
 writev:                        no
@@ -431,13 +431,6 @@ For many filesystems, it is probably safe to acquire the inode
 semaphore.  Note some filesystems (i.e. remote ones) provide no
 protection for i_size so you will need to use the BKL.
 
-->open() locking is in-transit: big lock partially moved into the methods.
-The only exception is ->open() in the instances of file_operations that never
-end up in ->i_fop/->proc_fops, i.e. ones that belong to character devices
-(chrdev_open() takes lock before replacing ->f_op and calling the secondary
-method. As soon as we fix the handling of module reference counters all
-instances of ->open() will be called without the BKL.
-
 Note: ext2_release() was *the* source of contention on fs-intensive
 loads and dropping BKL on ->release() helps to get rid of that (we still
 grab BKL for cases when we close a file that had been opened r/w, but that
index 394eb2cc1c39b8fa863459b796bc95a427957013..f566ad9bcb7b6a4a58deab30f085d85f0e39746e 100644 (file)
@@ -2413,6 +2413,8 @@ The following 4 memory types are supported:
   - (bit 1) anonymous shared memory
   - (bit 2) file-backed private memory
   - (bit 3) file-backed shared memory
+  - (bit 4) ELF header pages in file-backed private memory areas (it is
+            effective only if the bit 2 is cleared)
 
   Note that MMIO pages such as frame buffer are never dumped and vDSO pages
   are always dumped regardless of the bitmask status.
index 62d4af44ec4a2e0a4987d48687dc0bd1d01dcbf0..59df81c8da2b86dd71394ccb85ab34bc1cba4595 100644 (file)
@@ -271,14 +271,14 @@ CDROMCLOSETRAY                    pendant of CDROMEJECT
 
        usage:
 
-         ioctl(fd, CDROMEJECT, 0);
+         ioctl(fd, CDROMCLOSETRAY, 0);
 
        inputs:         none
 
        outputs:        none
 
        error returns:
-         ENOSYS        cd drive not capable of ejecting
+         ENOSYS        cd drive not capable of closing the tray
          EBUSY         other processes are accessing drive, or door is locked
 
        notes:
index 297ba7b1ccaf953ff85e486baa0a7547450db31c..2035bc4932f224685992ca57b29e64de5da4934e 100644 (file)
@@ -35,8 +35,9 @@ This file contains
     6.1 general settings
     6.2 local loopback of sent frames
     6.3 CAN controller hardware filters
-    6.4 currently supported CAN hardware
-    6.5 todo
+    6.4 The virtual CAN driver (vcan)
+    6.5 currently supported CAN hardware
+    6.6 todo
 
   7 Credits
 
@@ -584,7 +585,42 @@ solution for a couple of reasons:
   @133MHz with four SJA1000 CAN controllers from 2002 under heavy bus
   load without any problems ...
 
-  6.4 currently supported CAN hardware (September 2007)
+  6.4 The virtual CAN driver (vcan)
+
+  Similar to the network loopback devices, vcan offers a virtual local
+  CAN interface. A full qualified address on CAN consists of
+
+  - a unique CAN Identifier (CAN ID)
+  - the CAN bus this CAN ID is transmitted on (e.g. can0)
+
+  so in common use cases more than one virtual CAN interface is needed.
+
+  The virtual CAN interfaces allow the transmission and reception of CAN
+  frames without real CAN controller hardware. Virtual CAN network
+  devices are usually named 'vcanX', like vcan0 vcan1 vcan2 ...
+  When compiled as a module the virtual CAN driver module is called vcan.ko
+
+  Since Linux Kernel version 2.6.24 the vcan driver supports the Kernel
+  netlink interface to create vcan network devices. The creation and
+  removal of vcan network devices can be managed with the ip(8) tool:
+
+  - Create a virtual CAN network interface:
+       ip link add type vcan
+
+  - Create a virtual CAN network interface with a specific name 'vcan42':
+       ip link add dev vcan42 type vcan
+
+  - Remove a (virtual CAN) network interface 'vcan42':
+       ip link del vcan42
+
+  The tool 'vcan' from the SocketCAN SVN repository on BerliOS is obsolete.
+
+  Virtual CAN network device creation in older Kernels:
+  In Linux Kernel versions < 2.6.24 the vcan driver creates 4 vcan
+  netdevices at module load time by default. This value can be changed
+  with the module parameter 'numdev'. E.g. 'modprobe vcan numdev=8'
+
+  6.5 currently supported CAN hardware
 
   On the project website http://developer.berlios.de/projects/socketcan
   there are different drivers available:
@@ -603,7 +639,7 @@ solution for a couple of reasons:
 
   Please check the Mailing Lists on the berlios OSS project website.
 
-  6.5 todo (September 2007)
+  6.6 todo
 
   The configuration interface for CAN network drivers is still an open
   issue that has not been finalized in the socketcan project. Also the
diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt
new file mode 100644 (file)
index 0000000..0e6e592
--- /dev/null
@@ -0,0 +1,175 @@
+Linux Phonet protocol family
+============================
+
+Introduction
+------------
+
+Phonet is a packet protocol used by Nokia cellular modems for both IPC
+and RPC. With the Linux Phonet socket family, Linux host processes can
+receive and send messages from/to the modem, or any other external
+device attached to the modem. The modem takes care of routing.
+
+Phonet packets can be exchanged through various hardware connections
+depending on the device, such as:
+  - USB with the CDC Phonet interface,
+  - infrared,
+  - Bluetooth,
+  - an RS232 serial port (with a dedicated "FBUS" line discipline),
+  - the SSI bus with some TI OMAP processors.
+
+
+Packets format
+--------------
+
+Phonet packets have a common header as follows:
+
+  struct phonethdr {
+    uint8_t  pn_media;  /* Media type (link-layer identifier) */
+    uint8_t  pn_rdev;   /* Receiver device ID */
+    uint8_t  pn_sdev;   /* Sender device ID */
+    uint8_t  pn_res;    /* Resource ID or function */
+    uint16_t pn_length; /* Big-endian message byte length (minus 6) */
+    uint8_t  pn_robj;   /* Receiver object ID */
+    uint8_t  pn_sobj;   /* Sender object ID */
+  };
+
+On Linux, the link-layer header includes the pn_media byte (see below).
+The next 7 bytes are part of the network-layer header.
+
+The device ID is split: the 6 higher-order bits consitute the device
+address, while the 2 lower-order bits are used for multiplexing, as are
+the 8-bit object identifiers. As such, Phonet can be considered as a
+network layer with 6 bits of address space and 10 bits for transport
+protocol (much like port numbers in IP world).
+
+The modem always has address number zero. All other device have a their
+own 6-bit address.
+
+
+Link layer
+----------
+
+Phonet links are always point-to-point links. The link layer header
+consists of a single Phonet media type byte. It uniquely identifies the
+link through which the packet is transmitted, from the modem's
+perspective. Each Phonet network device shall prepend and set the media
+type byte as appropriate. For convenience, a common phonet_header_ops
+link-layer header operations structure is provided. It sets the
+media type according to the network device hardware address.
+
+Linux Phonet network interfaces support a dedicated link layer packets
+type (ETH_P_PHONET) which is out of the Ethernet type range. They can
+only send and receive Phonet packets.
+
+The virtual TUN tunnel device driver can also be used for Phonet. This
+requires IFF_TUN mode, _without_ the IFF_NO_PI flag. In this case,
+there is no link-layer header, so there is no Phonet media type byte.
+
+Note that Phonet interfaces are not allowed to re-order packets, so
+only the (default) Linux FIFO qdisc should be used with them.
+
+
+Network layer
+-------------
+
+The Phonet socket address family maps the Phonet packet header:
+
+  struct sockaddr_pn {
+    sa_family_t spn_family;    /* AF_PHONET */
+    uint8_t     spn_obj;       /* Object ID */
+    uint8_t     spn_dev;       /* Device ID */
+    uint8_t     spn_resource;  /* Resource or function */
+    uint8_t     spn_zero[...]; /* Padding */
+  };
+
+The resource field is only used when sending and receiving;
+It is ignored by bind() and getsockname().
+
+
+Low-level datagram protocol
+---------------------------
+
+Applications can send Phonet messages using the Phonet datagram socket
+protocol from the PF_PHONET family. Each socket is bound to one of the
+2^10 object IDs available, and can send and receive packets with any
+other peer.
+
+  struct sockaddr_pn addr = { .spn_family = AF_PHONET, };
+  ssize_t len;
+  socklen_t addrlen = sizeof(addr);
+  int fd;
+
+  fd = socket(PF_PHONET, SOCK_DGRAM, 0);
+  bind(fd, (struct sockaddr *)&addr, sizeof(addr));
+  /* ... */
+
+  sendto(fd, msg, msglen, 0, (struct sockaddr *)&addr, sizeof(addr));
+  len = recvfrom(fd, buf, sizeof(buf), 0,
+                 (struct sockaddr *)&addr, &addrlen);
+
+This protocol follows the SOCK_DGRAM connection-less semantics.
+However, connect() and getpeername() are not supported, as they did
+not seem useful with Phonet usages (could be added easily).
+
+
+Phonet Pipe protocol
+--------------------
+
+The Phonet Pipe protocol is a simple sequenced packets protocol
+with end-to-end congestion control. It uses the passive listening
+socket paradigm. The listening socket is bound to an unique free object
+ID. Each listening socket can handle up to 255 simultaneous
+connections, one per accept()'d socket.
+
+  int lfd, cfd;
+
+  lfd = socket(PF_PHONET, SOCK_SEQPACKET, PN_PROTO_PIPE);
+  listen (lfd, INT_MAX);
+
+  /* ... */
+  cfd = accept(lfd, NULL, NULL);
+  for (;;)
+  {
+    char buf[...];
+    ssize_t len = read(cfd, buf, sizeof(buf));
+
+    /* ... */
+
+    write(cfd, msg, msglen);
+  }
+
+Connections are established between two endpoints by a "third party"
+application. This means that both endpoints are passive; so connect()
+is not possible.
+
+WARNING:
+When polling a connected pipe socket for writability, there is an
+intrinsic race condition whereby writability might be lost between the
+polling and the writing system calls. In this case, the socket will
+block until write because possible again, unless non-blocking mode
+becomes enabled.
+
+
+The pipe protocol provides two socket options at the SOL_PNPIPE level:
+
+  PNPIPE_ENCAP accepts one integer value (int) of:
+
+    PNPIPE_ENCAP_NONE: The socket operates normally (default).
+
+    PNPIPE_ENCAP_IP: The socket is used as a backend for a virtual IP
+      interface. This requires CAP_NET_ADMIN capability. GPRS data
+      support on Nokia modems can use this. Note that the socket cannot
+      be reliably poll()'d or read() from while in this mode.
+
+  PNPIPE_IFINDEX is a read-only integer value. It contains the
+    interface index of the network interface created by PNPIPE_ENCAP,
+    or zero if encapsulation is off.
+
+
+Authors
+-------
+
+Linux Phonet was initially written by Sakari Ailus.
+Other contributors include Mikä Liljeberg, Andras Domokos,
+Carlos Chinea and Rémi Denis-Courmont.
+Copyright (C) 2008 Nokia Corporation.
index 276a7e6378227b5931be236104509fe62da2d4ad..e1ff0d920a5ce48b2a05d8f71584668e2817cf49 100644 (file)
@@ -351,9 +351,10 @@ kernel.  This value defaults to SHMMAX.
 
 softlockup_thresh:
 
-This value can be used to lower the softlockup tolerance
-threshold. The default threshold is 10s.  If a cpu is locked up
-for 10s, the kernel complains.  Valid values are 1-60s.
+This value can be used to lower the softlockup tolerance threshold.  The
+default threshold is 60 seconds.  If a cpu is locked up for 60 seconds,
+the kernel complains.  Valid values are 1-60 seconds.  Setting this
+tunable to zero will disable the softlockup detection altogether.
 
 ==============================================================
 
index 7304bcf5a3062fd58e70cfce160d85cab0dff7d5..5e6b64c20d258dbadf9b46f72f8717779ea05a6c 100644 (file)
@@ -42,9 +42,21 @@ This function kills all URBs associated with an anchor. The URBs
 are called in the reverse temporal order they were submitted.
 This way no data can be reordered.
 
+usb_unlink_anchored_urbs()
+--------------------------
+
+This function unlinks all URBs associated with an anchor. The URBs
+are processed in the reverse temporal order they were submitted.
+This is similar to usb_kill_anchored_urbs(), but it will not sleep.
+Therefore no guarantee is made that the URBs have been unlinked when
+the call returns. They may be unlinked later but will be unlinked in
+finite time.
+
 usb_wait_anchor_empty_timeout()
 -------------------------------
 
 This function waits for all URBs associated with an anchor to finish
 or a timeout, whichever comes first. Its return value will tell you
 whether the timeout was reached.
+
+
index 106684e45e15bd8ad3a68591caa0e1ebb4e4e6f0..e6aa6aa789f54ac1b5d626297851502b49f3baec 100644 (file)
@@ -271,20 +271,20 @@ W:        http://www.lesswatts.org/projects/acpi/
 S:     Supported
 
 ACPI WMI DRIVER
-P:      Carlos Corbacho
-M:      carlos@strangeworlds.co.uk
-L:      linux-acpi@vger.kernel.org
-W:      http://www.lesswatts.org/projects/acpi/
-S:      Maintained
+P:     Carlos Corbacho
+M:     carlos@strangeworlds.co.uk
+L:     linux-acpi@vger.kernel.org
+W:     http://www.lesswatts.org/projects/acpi/
+S:     Maintained
 
 AD1889 ALSA SOUND DRIVER
-P:     Kyle McMartin
-M:     kyle@mcmartin.ca
-P:     Thibaut Varene
-M:     T-Bone@parisc-linux.org
-W:     http://wiki.parisc-linux.org/AD1889
-L:     linux-parisc@vger.kernel.org
-S:     Maintained
+P:     Kyle McMartin
+M:     kyle@mcmartin.ca
+P:     Thibaut Varene
+M:     T-Bone@parisc-linux.org
+W:     http://wiki.parisc-linux.org/AD1889
+L:     linux-parisc@vger.kernel.org
+S:     Maintained
 
 ADM1025 HARDWARE MONITOR DRIVER
 P:     Jean Delvare
@@ -473,11 +473,11 @@ L:        linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:     Maintained
 
 ARM/ATMEL AT91RM9200 ARM ARCHITECTURE
-P:      Andrew Victor
-M:      linux@maxim.org.za
-L:      linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
-W:      http://maxim.org.za/at91_26.html
-S:      Maintained
+P:     Andrew Victor
+M:     linux@maxim.org.za
+L:     linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
+W:     http://maxim.org.za/at91_26.html
+S:     Maintained
 
 ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE
 P:     Lennert Buytenhek
@@ -532,10 +532,10 @@ L:        linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 S:     Maintained
 
 ARM/HP JORNADA 7XX MACHINE SUPPORT
-P:      Kristoffer Ericson
-M:      kristoffer.ericson@gmail.com
-W:      www.jlime.com
-S:      Maintained
+P:     Kristoffer Ericson
+M:     kristoffer.ericson@gmail.com
+W:     www.jlime.com
+S:     Maintained
 
 ARM/INTEL IOP32X ARM ARCHITECTURE
 P:     Lennert Buytenhek
@@ -750,11 +750,13 @@ P:        Ville Syrjala
 M:     syrjala@sci.fi
 S:     Maintained
 
-ATL1 ETHERNET DRIVER
+ATLX ETHERNET DRIVERS
 P:     Jay Cliburn
 M:     jcliburn@gmail.com
 P:     Chris Snook
 M:     csnook@redhat.com
+P:     Jie Yang
+M:     jie.yang@atheros.com
 L:     atl1-devel@lists.sourceforge.net
 W:     http://sourceforge.net/projects/atl1
 W:     http://atl1.sourceforge.net
@@ -1015,7 +1017,7 @@ T:        git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:     Maintained
 
 CAFE CMOS INTEGRATED CAMERA CONTROLLER DRIVER
-P:     Jonathan Corbet
+P:     Jonathan Corbet
 M:     corbet@lwn.net
 L:     video4linux-list@redhat.com
 S:     Maintained
@@ -1364,7 +1366,7 @@ P:        Digi International, Inc
 M:     Eng.Linux@digi.com
 L:     Eng.Linux@digi.com
 W:     http://www.digi.com
-S:     Orphaned
+S:     Orphan
 
 DIRECTORY NOTIFICATION
 P:     Stephen Rothwell
@@ -1428,12 +1430,12 @@ L:      linux-acpi@vger.kernel.org
 S:     Supported
 
 DOCUMENTATION (/Documentation directory)
-P:     Michael Kerrisk
-M:     mtk.manpages@gmail.com
-P:     Randy Dunlap
-M:     rdunlap@xenotime.net
-L:     linux-doc@vger.kernel.org
-S:     Maintained
+P:     Michael Kerrisk
+M:     mtk.manpages@gmail.com
+P:     Randy Dunlap
+M:     rdunlap@xenotime.net
+L:     linux-doc@vger.kernel.org
+S:     Maintained
 
 DOUBLETALK DRIVER
 P:     James R. Van Zandt
@@ -1464,7 +1466,7 @@ S:        Maintained
 DVB SUBSYSTEM AND DRIVERS
 P:     LinuxTV.org Project
 M:     v4l-dvb-maintainer@linuxtv.org
-L:     linux-dvb@linuxtv.org (subscription required)
+L:     linux-dvb@linuxtv.org (subscription required)
 W:     http://linuxtv.org/
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:     Maintained
@@ -1802,7 +1804,7 @@ FUTURE DOMAIN TMC-16x0 SCSI DRIVER (16-bit)
 P:     Rik Faith
 M:     faith@cs.unc.edu
 L:     linux-scsi@vger.kernel.org
-S:     Odd fixes (e.g., new signatures)
+S:     Odd Fixes (e.g., new signatures)
 
 GDT SCSI DISK ARRAY CONTROLLER DRIVER
 P:     Achim Leubner
@@ -1843,10 +1845,10 @@ S:      Maintained
 HARDWARE MONITORING
 L:     lm-sensors@lm-sensors.org
 W:     http://www.lm-sensors.org/
-S:     Orphaned
+S:     Orphan
 
 HARDWARE RANDOM NUMBER GENERATOR CORE
-S:     Orphaned
+S:     Orphan
 
 HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
 P:     Robert Love
@@ -1989,7 +1991,7 @@ S:        Maintained
 I2C/SMBUS STUB DRIVER
 P:     Mark M. Hoffman
 M:     mhoffman@lightlink.com
-L:     lm-sensors@lm-sensors.org
+L:     i2c@lm-sensors.org
 S:     Maintained
 
 I2C SUBSYSTEM
@@ -2113,7 +2115,7 @@ M:        rolandd@cisco.com
 P:     Sean Hefty
 M:     sean.hefty@intel.com
 P:     Hal Rosenstock
-M:     hal.rosenstock@gmail.com 
+M:     hal.rosenstock@gmail.com
 L:     general@lists.openfabrics.org
 W:     http://www.openib.org/
 T:     git kernel.org:/pub/scm/linux/kernel/git/roland/infiniband.git
@@ -2707,17 +2709,17 @@ S:      Maintained
 
 MARVELL YUKON / SYSKONNECT DRIVER
 P:     Mirko Lindner
-M:     mlindner@syskonnect.de
+M:     mlindner@syskonnect.de
 P:     Ralph Roesler
-M:     rroesler@syskonnect.de
-W:     http://www.syskonnect.com
-S:     Supported
+M:     rroesler@syskonnect.de
+W:     http://www.syskonnect.com
+S:     Supported
 
 MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
 P:     Michael Kerrisk
 M:     mtk.manpages@gmail.com
-W:     http://www.kernel.org/doc/man-pages
-S:     Supported
+W:     http://www.kernel.org/doc/man-pages
+S:     Supported
 
 MARVELL LIBERTAS WIRELESS DRIVER
 P:     Dan Williams
@@ -2746,7 +2748,7 @@ S:        Maintained
 MEGARAID SCSI DRIVERS
 P:     Neela Syam Kolli
 M:     megaraidlinux@lsi.com
-S:     linux-scsi@vger.kernel.org
+L:     linux-scsi@vger.kernel.org
 W:     http://megaraid.lsilogic.com
 S:     Maintained
 
@@ -2864,7 +2866,7 @@ MULTIMEDIA CARD (MMC) ETC. OVER SPI
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
 L:     linux-kernel@vger.kernel.org
-S:     Odd fixes
+S:     Odd Fixes
 
 MULTISOUND SOUND DRIVER
 P:     Andrew Veliath
@@ -2878,10 +2880,10 @@ L:      linux-kernel@vger.kernel.org
 S:     Maintained
 
 MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
-P:     Felipe Balbi
-M:     felipe.balbi@nokia.com
-L:     linux-usb@vger.kernel.org
-S:     Maintained
+P:     Felipe Balbi
+M:     felipe.balbi@nokia.com
+L:     linux-usb@vger.kernel.org
+S:     Maintained
 
 MYRICOM MYRI-10G 10GbE DRIVER (MYRI10GE)
 P:     Andrew Gallatin
@@ -2893,7 +2895,7 @@ W:        http://www.myri.com/scs/download-Myri10GE.html
 S:     Supported
 
 NATSEMI ETHERNET DRIVER (DP8381x)
-P:     Tim Hockin
+P:     Tim Hockin
 M:     thockin@hockin.org
 S:     Maintained
 
@@ -3112,7 +3114,7 @@ M:        laforge@gnumonks.org
 S:     Maintained
 
 OMNIVISION OV7670 SENSOR DRIVER
-P:     Jonathan Corbet
+P:     Jonathan Corbet
 M:     corbet@lwn.net
 L:     video4linux-list@redhat.com
 S:     Maintained
@@ -3222,7 +3224,7 @@ T:        git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
 S:     Supported
 
 PCI HOTPLUG CORE
-P:     Kristen Carlson Accardi
+P:     Kristen Carlson Accardi
 M:     kristen.c.accardi@intel.com
 S:     Supported
 
@@ -3668,7 +3670,7 @@ M:        jmorris@namei.org
 P:     Eric Paris
 M:     eparis@parisplace.org
 L:     linux-kernel@vger.kernel.org (kernel issues)
-L:     selinux@tycho.nsa.gov (subscribers-only, general discussion)
+L:     selinux@tycho.nsa.gov (subscribers-only, general discussion)
 W:     http://www.nsa.gov/selinux
 S:     Supported
 
@@ -3744,7 +3746,7 @@ S:        Maintained
 SIS 96X I2C/SMBUS DRIVER
 P:     Mark M. Hoffman
 M:     mhoffman@lightlink.com
-L:     lm-sensors@lm-sensors.org
+L:     i2c@lm-sensors.org
 S:     Maintained
 
 SIS FRAMEBUFFER DRIVER
@@ -3786,10 +3788,10 @@ M:      bn@niasdigital.com
 S:     Maintained
 
 SOC-CAMERA V4L2 SUBSYSTEM
-P:     Guennadi Liakhovetski
-M:     g.liakhovetski@gmx.de
-L:     video4linux-list@redhat.com
-S:     Maintained
+P:     Guennadi Liakhovetski
+M:     g.liakhovetski@gmx.de
+L:     video4linux-list@redhat.com
+S:     Maintained
 
 SOFTWARE RAID (Multiple Disks) SUPPORT
 P:     Ingo Molnar
@@ -3851,11 +3853,12 @@ S:      Maintained
 
 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT
 P:     Liam Girdwood
-M:     liam.girdwood@wolfsonmicro.com
+M:     lrg@slimlogic.co.uk
 P:     Mark Brown
 M:     broonie@opensource.wolfsonmicro.com
 T:     git opensource.wolfsonmicro.com/linux-2.6-asoc
 L:     alsa-devel@alsa-project.org (subscribers-only)
+W:     http://alsa-project.org/main/index.php/ASoC
 S:     Supported
 
 SPI SUBSYSTEM
@@ -3943,7 +3946,7 @@ S:        Maintained
 
 STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
 W:     http://mosquitonet.Stanford.EDU/strip.html
-S:     Unsupported ?
+S:     Orphan
 
 STRADIS MPEG-2 DECODER DRIVER
 P:     Nathan Laredo
@@ -4024,9 +4027,9 @@ T:        git repo.or.cz/linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git
 S:     Maintained
 
 TI FLASH MEDIA INTERFACE DRIVER
-P:      Alex Dubov
-M:      oakad@yahoo.com
-S:      Maintained
+P:     Alex Dubov
+M:     oakad@yahoo.com
+S:     Maintained
 
 TI OMAP MMC INTERFACE DRIVER
 P:     Carlos Aguiar, Anderson Briglia and Syed Khasim
@@ -4172,13 +4175,13 @@ USB BLOCK DRIVER (UB ub)
 P:     Pete Zaitcev
 M:     zaitcev@redhat.com
 L:     linux-kernel@vger.kernel.org
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Supported
 
 USB CDC ETHERNET DRIVER
 P:     Greg Kroah-Hartman
 M:     greg@kroah.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 W:     http://www.kroah.com/linux-usb/
 
@@ -4205,13 +4208,13 @@ S:      Maintained
 USB EHCI DRIVER
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Odd Fixes
 
 USB ET61X[12]51 DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
@@ -4219,33 +4222,33 @@ S:      Maintained
 USB GADGET/PERIPHERAL SUBSYSTEM
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.linux-usb.org/gadget
 S:     Maintained
 
 USB HID/HIDBP DRIVERS (USB KEYBOARDS, MICE, REMOTE CONTROLS, ...)
 P:     Jiri Kosina
 M:     jkosina@suse.cz
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/jikos/hid.git
 S:     Maintained
 
 USB ISP116X DRIVER
 P:     Olav Kongas
 M:     ok@artecdesign.ee
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB KAWASAKI LSI DRIVER
 P:     Oliver Neukum
 M:     oliver@neukum.name
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB MASS STORAGE DRIVER
 P:     Matthew Dharm
 M:     mdharm-usb@one-eyed-alien.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     usb-storage@lists.one-eyed-alien.net
 S:     Maintained
 W:     http://www.one-eyed-alien.net/~mdharm/linux-usb/
@@ -4253,26 +4256,26 @@ W:      http://www.one-eyed-alien.net/~mdharm/linux-usb/
 USB OHCI DRIVER
 P:     David Brownell
 M:     dbrownell@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Odd Fixes
 
 USB OPTION-CARD DRIVER
 P:     Matthias Urlichs
 M:     smurf@smurf.noris.de
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB OV511 DRIVER
 P:     Mark McClelland
 M:     mmcclell@bigfoot.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://alpha.dyndns.org/ov511/
 S:     Maintained
 
 USB PEGASUS DRIVER
 P:     Petko Manolov
 M:     petkan@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     netdev@vger.kernel.org
 W:     http://pegasus2.sourceforge.net/
 S:     Maintained
@@ -4280,13 +4283,13 @@ S:      Maintained
 USB PRINTER DRIVER (usblp)
 P:     Pete Zaitcev
 M:     zaitcev@redhat.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Supported
 
 USB RTL8150 DRIVER
 P:     Petko Manolov
 M:     petkan@users.sourceforge.net
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     netdev@vger.kernel.org
 W:     http://pegasus2.sourceforge.net/
 S:     Maintained
@@ -4294,20 +4297,20 @@ S:      Maintained
 USB SE401 DRIVER
 P:     Jeroen Vreeken
 M:     pe1rxq@amsat.org
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.chello.nl/~j.vreeken/se401/
 S:     Maintained
 
 USB SERIAL BELKIN F5U103 DRIVER
 P:     William Greathouse
 M:     wgreathouse@smva.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB SERIAL CYPRESS M8 DRIVER
 P:     Lonnie Mendez
 M:     dignome@gmail.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 W:     http://geocities.com/i0xox0i
 W:     http://firstlight.net/cvs
@@ -4322,39 +4325,39 @@ USB SERIAL DIGI ACCELEPORT DRIVER
 P:     Peter Berger and Al Borchers
 M:     pberger@brimson.com
 M:     alborchers@steinerpoint.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB SERIAL DRIVER
 P:     Greg Kroah-Hartman
 M:     gregkh@suse.de
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Supported
 
 USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER
 P:     Gary Brubaker
 M:     xavyer@ix.netcom.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB SERIAL KEYSPAN DRIVER
 P:     Greg Kroah-Hartman
 M:     greg@kroah.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.kroah.com/linux/
 S:     Maintained
 
 USB SERIAL WHITEHEAT DRIVER
 P:     Support Department
 M:     support@connecttech.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.connecttech.com
 S:     Supported
 
 USB SN9C1xx DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
@@ -4362,7 +4365,7 @@ S:        Maintained
 USB SUBSYSTEM
 P:     Greg Kroah-Hartman
 M:     gregkh@suse.de
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://www.linux-usb.org
 T:     quilt kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
 S:     Supported
@@ -4370,7 +4373,7 @@ S:        Supported
 USB UHCI DRIVER
 P:     Alan Stern
 M:     stern@rowland.harvard.edu
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 S:     Maintained
 
 USB "USBNET" DRIVER FRAMEWORK
@@ -4383,7 +4386,7 @@ S:        Maintained
 USB VIDEO CLASS
 P:     Laurent Pinchart
 M:     laurent.pinchart@skynet.be
-L:     linx-uvc-devel@berlios.de
+L:     linux-uvc-devel@lists.berlios.de
 L:     video4linux-list@redhat.com
 W:     http://linux-uvc.berlios.de
 S:     Maintained
@@ -4391,7 +4394,7 @@ S:        Maintained
 USB W996[87]CF DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
@@ -4405,7 +4408,7 @@ S:        Maintained
 USB ZC0301 DRIVER
 P:     Luca Risolia
 M:     luca.risolia@studio.unibo.it
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://www.linux-projects.org
 S:     Maintained
@@ -4413,14 +4416,14 @@ S:      Maintained
 USB ZD1201 DRIVER
 P:     Jeroen Vreeken
 M:     pe1rxq@amsat.org
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 W:     http://linux-lc100020.sourceforge.net
 S:     Maintained
 
 USB ZR364XX DRIVER
 P:     Antoine Jacquet
 M:     royale@zerezo.com
-L:      linux-usb@vger.kernel.org
+L:     linux-usb@vger.kernel.org
 L:     video4linux-list@redhat.com
 W:     http://royale.zerezo.com/zr364xx/
 S:     Maintained
index f448e0082ebf6726ba4a644164e5194edced6ff0..1d03c1644ddbffe9dbec85d05b3faceafbe01c77 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 27
-EXTRAVERSION = -rc5
+EXTRAVERSION = -rc8
 NAME = Rotary Wombat
 
 # *DOCUMENTATION*
index 721c03d53f4b34ce07ae7e8c23f69942ac1e5c4f..918d0cbbf06416167bfc1d34ac58d31ab2f0cb5c 100644 (file)
@@ -30,7 +30,7 @@ static inline void pcibios_penalize_isa_irq(int irq, int active)
  * The networking and block device layers use this boolean for bounce
  * buffer decisions.
  */
-#define PCI_DMA_BUS_IS_PHYS     (0)
+#define PCI_DMA_BUS_IS_PHYS     (1)
 
 /*
  * Whether pci_unmap_{single,page} is a nop depends upon the
index aaffaecffcd13699dfd0cd51d2eaf61608e4a94d..ba8ccfede964d93a81c061633bd969916d85ebd5 100644 (file)
@@ -111,8 +111,6 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
        case 'D':
        case 'k':
        case 'c':
-               kgdb_contthread = NULL;
-
                /*
                 * Try to read optional parameter, pc unchanged if no parm.
                 * If this was a compiled breakpoint, we need to move
index 720c48b9ee0404257cd218a3fe26b66a035a653d..aa2fc375a3257fcb4a1e5b8e468dc1af7c494650 100644 (file)
@@ -70,9 +70,6 @@ void davinci_psc_config(unsigned int domain, unsigned int id, char enable)
 {
        u32 epcpr, ptcmd, ptstat, pdstat, pdctl1, mdstat, mdctl, mdstat_mask;
 
-       if (id < 0)
-               return;
-
        mdctl = davinci_readl(DAVINCI_PWR_SLEEP_CNTRL_BASE + MDCTL + 4 * id);
        if (enable)
                mdctl |= 0x00000003;    /* Enable Module */
index 610fb24d8ae2ed4fcbc7e9220a5849508ef5a5cb..cd317795f3559779e3ac788fff66028b243b3cd6 100644 (file)
@@ -25,7 +25,7 @@
 #include "common.h"
 
 static struct mv643xx_eth_platform_data db88f6281_ge00_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 static struct mv_sata_platform_data db88f6281_sata_data = {
index a3012d4459714c7932d533bd73a805523465ac36..b1d1a87a6821f9b3e53d819fd31cdefc1b8b491d 100644 (file)
@@ -30,7 +30,7 @@
 #define RD88F6192_GPIO_USB_VBUS                10
 
 static struct mv643xx_eth_platform_data rd88f6192_ge00_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 static struct mv_sata_platform_data rd88f6192_sata_data = {
index d96487a0f18bfabe9fbca93a5ba24962e64262a3..b6416615c0b9c0667157c257f733c4cfce30c0b4 100644 (file)
@@ -69,7 +69,7 @@ static struct platform_device rd88f6281_nand_flash = {
 };
 
 static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
-       .phy_addr       = -1,
+       .phy_addr       = MV643XX_ETH_PHY_NONE,
        .speed          = SPEED_1000,
        .duplex         = DUPLEX_FULL,
 };
index 2cc9ac9b488f24cb8b87a72f50530cd6a34a4be5..85f9c1296aa02675d7c131a85e8c12161a437919 100644 (file)
@@ -67,7 +67,7 @@ static struct platform_device lb88rc8480_boot_flash = {
 };
 
 static struct mv643xx_eth_platform_data lb88rc8480_ge0_data = {
-       .phy_addr       = 1,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(1),
        .mac_addr       = { 0x00, 0x50, 0x43, 0x11, 0x22, 0x33 },
 };
 
index 953a26c469cb0b9cf0602ec038e75d81129b7405..5842d3bb02b27df67962d2c2140bbd3f5b5295e8 100644 (file)
@@ -330,6 +330,7 @@ void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = {
        .t_clk          = 0,
        .dram           = &mv78xx0_mbus_dram_info,
+       .shared_smi     = &mv78xx0_ge00_shared,
 };
 
 static struct resource mv78xx0_ge01_shared_resources[] = {
@@ -370,7 +371,6 @@ static struct platform_device mv78xx0_ge01 = {
 void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
 {
        eth_data->shared = &mv78xx0_ge01_shared;
-       eth_data->shared_smi = &mv78xx0_ge00_shared;
        mv78xx0_ge01.dev.platform_data = eth_data;
 
        platform_device_register(&mv78xx0_ge01_shared);
@@ -384,6 +384,7 @@ void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
 struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = {
        .t_clk          = 0,
        .dram           = &mv78xx0_mbus_dram_info,
+       .shared_smi     = &mv78xx0_ge00_shared,
 };
 
 static struct resource mv78xx0_ge10_shared_resources[] = {
@@ -424,7 +425,6 @@ static struct platform_device mv78xx0_ge10 = {
 void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
 {
        eth_data->shared = &mv78xx0_ge10_shared;
-       eth_data->shared_smi = &mv78xx0_ge00_shared;
        mv78xx0_ge10.dev.platform_data = eth_data;
 
        platform_device_register(&mv78xx0_ge10_shared);
@@ -438,6 +438,7 @@ void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
 struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = {
        .t_clk          = 0,
        .dram           = &mv78xx0_mbus_dram_info,
+       .shared_smi     = &mv78xx0_ge00_shared,
 };
 
 static struct resource mv78xx0_ge11_shared_resources[] = {
@@ -478,7 +479,6 @@ static struct platform_device mv78xx0_ge11 = {
 void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
 {
        eth_data->shared = &mv78xx0_ge11_shared;
-       eth_data->shared_smi = &mv78xx0_ge00_shared;
        mv78xx0_ge11.dev.platform_data = eth_data;
 
        platform_device_register(&mv78xx0_ge11_shared);
index a2d0c97836047441ccf486a5629f1b5a20c9e27b..49f434c39eb76e539f46e81be52d9735f7ca5145 100644 (file)
 #include "common.h"
 
 static struct mv643xx_eth_platform_data db78x00_ge00_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 static struct mv643xx_eth_platform_data db78x00_ge01_data = {
-       .phy_addr       = 9,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(9),
 };
 
 static struct mv643xx_eth_platform_data db78x00_ge10_data = {
-       .phy_addr       = -1,
+       .phy_addr       = MV643XX_ETH_PHY_NONE,
 };
 
 static struct mv643xx_eth_platform_data db78x00_ge11_data = {
-       .phy_addr       = -1,
+       .phy_addr       = MV643XX_ETH_PHY_NONE,
 };
 
 static struct mv_sata_platform_data db78x00_sata_data = {
index 0a152ed15a85a44739b4f69c10b8ffbcab0c444b..df8582a6231b3a9ee7ce940b660ed891400bc30d 100644 (file)
@@ -54,7 +54,7 @@ static struct platform_device pcm037_flash = {
 };
 
 static struct imxuart_platform_data uart_pdata = {
-       .flags = 0,
+       .flags = IMXUART_HAVE_RTSCTS,
 };
 
 static struct platform_device *devices[] __initdata = {
index ff13e9060b180a9f83c6b0ed2ab5cf4f9d43c205..d318bea2af91bbb5e9ec46a57813d6ef5add40e7 100644 (file)
@@ -285,7 +285,7 @@ subsys_initcall(db88f5281_pci_init);
  * Ethernet
  ****************************************************************************/
 static struct mv643xx_eth_platform_data db88f5281_eth_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 /*****************************************************************************
index b38c65ccfb154b63b584b310ca1539e4c886b08f..3e66098340a538b146c357d51d0fab4218ee313a 100644 (file)
@@ -79,7 +79,7 @@ subsys_initcall(dns323_pci_init);
  */
 
 static struct mv643xx_eth_platform_data dns323_eth_data = {
-       .phy_addr = 8,
+       .phy_addr = MV643XX_ETH_PHY_ADDR(8),
 };
 
 /****************************************************************************
index e321ec331839c1f8e68959bbe8a3ff1e44030f54..610f2a6297f87c893df7a637fa6a7aabcdf4552e 100644 (file)
@@ -161,7 +161,7 @@ subsys_initcall(kurobox_pro_pci_init);
  ****************************************************************************/
 
 static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 /*****************************************************************************
index 53ff1893b8835e111406affb4dea47d8b835c6d4..68acca98e638e62efa25b2d3ae12e558a6eec570 100644 (file)
@@ -109,7 +109,7 @@ subsys_initcall(mss2_pci_init);
  ****************************************************************************/
 
 static struct mv643xx_eth_platform_data mss2_eth_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 /*****************************************************************************
index 978d4d5993964f93baa09bf387c55881d52494cb..97c9ccb2ac60f7713bc076e38b3b23b8dff94c04 100644 (file)
@@ -39,7 +39,7 @@
  * Ethernet
  ****************************************************************************/
 static struct mv643xx_eth_platform_data mv2120_eth_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 static struct mv_sata_platform_data mv2120_sata_data = {
index e72fe1e065e825069547e166763f33adaf32b3b1..500cdadaf09c8e160f566b37a1fb785e39437cce 100644 (file)
@@ -88,7 +88,7 @@ static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = {
 };
 
 static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
-       .phy_addr       = -1,
+       .phy_addr       = MV643XX_ETH_PHY_NONE,
        .speed          = SPEED_1000,
        .duplex         = DUPLEX_FULL,
 };
index a1fe3257320d77732c121eeb9b7c07b25557909e..ebde8141649935058d7a701b485e7a6b412cccd7 100644 (file)
@@ -89,7 +89,7 @@ static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = {
 };
 
 static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
-       .phy_addr       = -1,
+       .phy_addr       = MV643XX_ETH_PHY_NONE,
        .speed          = SPEED_1000,
        .duplex         = DUPLEX_FULL,
 };
index 4c3bcd76ac85ba0ca55f1b40510ac0e93ef04f62..a04f9e4b633a409a10a80cfb5c63da32f4ce3793 100644 (file)
@@ -221,7 +221,7 @@ subsys_initcall(rd88f5182_pci_init);
  ****************************************************************************/
 
 static struct mv643xx_eth_platform_data rd88f5182_eth_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 /*****************************************************************************
index ae0a5dccd2a1f465ae9ce4cd3a657d1ffe4a878f..1368e9fd1a06806d629d21db2667086fe3c7b7ae 100644 (file)
@@ -103,8 +103,7 @@ static struct platform_device ts78xx_nor_boot_flash = {
  * Ethernet
  ****************************************************************************/
 static struct mv643xx_eth_platform_data ts78xx_eth_data = {
-       .phy_addr       = 0,
-       .force_phy_addr = 1,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
 };
 
 /*****************************************************************************
index 83feac3147a60d257da59957e2b40d67d632c3dc..19cde24fbfdf91a6bec33d628ebe510de20f1d64 100644 (file)
@@ -48,7 +48,7 @@ void qnap_tsx09_power_off(void)
  ****************************************************************************/
 
 struct mv643xx_eth_platform_data qnap_tsx09_eth_data = {
-       .phy_addr       = 8,
+       .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
 };
 
 static int __init qnap_tsx09_parse_hex_nibble(char n)
index b6bc43e07eed1cce12d21dd0cfdb8cadeb4537ae..7ddc22c2bb5480d17455fe533023ddd36d66a58f 100644 (file)
@@ -92,7 +92,7 @@ static struct platform_device wnr854t_nor_flash = {
 };
 
 static struct mv643xx_eth_platform_data wnr854t_eth_data = {
-       .phy_addr       = -1,
+       .phy_addr       = MV643XX_ETH_PHY_NONE,
        .speed          = SPEED_1000,
        .duplex         = DUPLEX_FULL,
 };
index b10da17b3fbdc0dc8842df785a23f7dbcc5db089..9a4fd5256462e8686b81643e47fe9c8987165f10 100644 (file)
@@ -100,7 +100,7 @@ static struct platform_device wrt350n_v2_nor_flash = {
 };
 
 static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
-       .phy_addr       = -1,
+       .phy_addr       = MV643XX_ETH_PHY_NONE,
        .speed          = SPEED_1000,
        .duplex         = DUPLEX_FULL,
 };
index 67e18509d7bfe6103b4d5062a307c0fe12c029e8..b0d6b32654cf622d13a9ac91073a2f1426381d97 100644 (file)
@@ -17,9 +17,9 @@
 #include <linux/interrupt.h>
 #include <linux/clockchips.h>
 #include <linux/sched.h>
+#include <linux/cnt32_to_63.h>
 
 #include <asm/div64.h>
-#include <asm/cnt32_to_63.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <mach/pxa-regs.h>
index 5dab30eafddc83c750d46a7990b51c1c032c8271..9f3ef9eb32e37366d0ecf5d3b6e8d1abaada4fab 100644 (file)
@@ -50,6 +50,7 @@
 #include <asm/mach/sharpsl_param.h>
 
 #include "generic.h"
+#include "clock.h"
 #include "devices.h"
 
 static unsigned long tosa_pin_config[] = {
@@ -521,6 +522,14 @@ static struct gpio_keys_button tosa_gpio_keys[] = {
                .wakeup = 1,
                .active_low = 1,
        },
+       {
+               .type   = EV_SW,
+               .code   = SW_HEADPHONE_INSERT,
+               .gpio   = TOSA_GPIO_EAR_IN,
+               .desc   = "HeadPhone insert",
+               .active_low = 1,
+               .debounce_interval = 300,
+       },
 };
 
 static struct gpio_keys_platform_data tosa_gpio_keys_platform_data = {
@@ -792,6 +801,8 @@ static void __init tosa_init(void)
        pxa_set_i2c_info(NULL);
        platform_scoop_config = &tosa_pcmcia_config;
 
+       clk_add_alias("CLK_CK3P6MI", &tc6393xb_device.dev, "GPIO11_CLK", NULL);
+
        platform_add_devices(devices, ARRAY_SIZE(devices));
 }
 
index 1362994c78aa1ede98cdc4661cb1cb56623378e0..b422526f6d8baa3fb504b23ddc24ffc57f41512e 100644 (file)
@@ -18,9 +18,9 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>       /* just for sched_clock() - funny that */
 #include <linux/platform_device.h>
+#include <linux/cnt32_to_63.h>
 
 #include <asm/div64.h>
-#include <asm/cnt32_to_63.h>
 #include <mach/hardware.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
index bc120850d313c1ea44e88fa99b76f93f833e6be9..cc6b4bfcecf6625edb3ad2a9b392b64f661db292 100644 (file)
@@ -1,10 +1,10 @@
 /*
  * arch/arm/mach-sa1100/include/mach/jornada720.h
  *
- * This file contains SSP/MCU communication definitions for HP Jornada 710/720/728
+ * SSP/MCU communication definitions for HP Jornada 710/720/728
  *
- * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
- *  Copyright (C) 2000 John Ankcorn <jca@lcs.mit.edu>
+ * Copyright 2007,2008 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ *  Copyright 2000 John Ankcorn <jca@lcs.mit.edu>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -25,3 +25,8 @@
 #define PWMOFF                 0xDF
 #define TXDUMMY                        0x11
 #define ERRORCODE              0x00
+
+extern void jornada_ssp_start(void);
+extern void jornada_ssp_end(void);
+extern int jornada_ssp_inout(u8 byte);
+extern int jornada_ssp_byte(u8 byte);
index 06ea7abd917009401e3bc1e5d0498ec8ed705507..28cf3696797705a3b263f14854675498d279f068 100644 (file)
@@ -21,8 +21,8 @@
 #include <linux/slab.h>
 
 #include <mach/hardware.h>
-#include <asm/hardware/ssp.h>
 #include <mach/jornada720.h>
+#include <asm/hardware/ssp.h>
 
 static DEFINE_SPINLOCK(jornada_ssp_lock);
 static unsigned long jornada_ssp_flags;
@@ -109,12 +109,12 @@ EXPORT_SYMBOL(jornada_ssp_inout);
  * jornada_ssp_start - enable mcu
  *
  */
-int jornada_ssp_start()
+void jornada_ssp_start(void)
 {
        spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags);
        GPCR = GPIO_GPIO25;
        udelay(50);
-       return 0;
+       return;
 };
 EXPORT_SYMBOL(jornada_ssp_start);
 
@@ -122,11 +122,11 @@ EXPORT_SYMBOL(jornada_ssp_start);
  * jornada_ssp_end - disable mcu and turn off lock
  *
  */
-int jornada_ssp_end()
+void jornada_ssp_end(void)
 {
        GPSR = GPIO_GPIO25;
        spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags);
-       return 0;
+       return;
 };
 EXPORT_SYMBOL(jornada_ssp_end);
 
index d75e795c893e494b725f4ad177350651e32a60e6..b638f10411e8e27b573f926133e141922512204b 100644 (file)
@@ -28,8 +28,8 @@
 #include <linux/amba/clcd.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/cnt32_to_63.h>
 
-#include <asm/cnt32_to_63.h>
 #include <asm/system.h>
 #include <mach/hardware.h>
 #include <asm/io.h>
index 187e3d8bfdfe89512a454c128b0de4d8cb97a3b6..01da719a745366309dedb2a78ac17216dbbd342b 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <mach/tc.h>
 #include <mach/board.h>
+#include <mach/mmc.h>
 #include <mach/mux.h>
 #include <mach/gpio.h>
 #include <mach/menelaus.h>
@@ -194,25 +195,38 @@ void omap_mcbsp_register_board_cfg(struct omap_mcbsp_platform_data *config,
 
 /*-------------------------------------------------------------------------*/
 
-#if    defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+#if    defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+       defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
 
-#ifdef CONFIG_ARCH_OMAP24XX
+#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
 #define        OMAP_MMC1_BASE          0x4809c000
-#define OMAP_MMC1_INT          INT_24XX_MMC_IRQ
+#define        OMAP_MMC1_END           (OMAP_MMC1_BASE + 0x1fc)
+#define        OMAP_MMC1_INT           INT_24XX_MMC_IRQ
+
+#define        OMAP_MMC2_BASE          0x480b4000
+#define        OMAP_MMC2_END           (OMAP_MMC2_BASE + 0x1fc)
+#define        OMAP_MMC2_INT           INT_24XX_MMC2_IRQ
+
 #else
+
 #define        OMAP_MMC1_BASE          0xfffb7800
+#define        OMAP_MMC1_END           (OMAP_MMC1_BASE + 0x7f)
 #define OMAP_MMC1_INT          INT_MMC
-#endif
+
 #define        OMAP_MMC2_BASE          0xfffb7c00      /* omap16xx only */
+#define        OMAP_MMC2_END           (OMAP_MMC2_BASE + 0x7f)
+#define        OMAP_MMC2_INT           INT_1610_MMC2
+
+#endif
 
-static struct omap_mmc_conf mmc1_conf;
+static struct omap_mmc_platform_data mmc1_data;
 
 static u64 mmc1_dmamask = 0xffffffff;
 
 static struct resource mmc1_resources[] = {
        {
                .start          = OMAP_MMC1_BASE,
-               .end            = OMAP_MMC1_BASE + 0x7f,
+               .end            = OMAP_MMC1_END,
                .flags          = IORESOURCE_MEM,
        },
        {
@@ -226,26 +240,27 @@ static struct platform_device mmc_omap_device1 = {
        .id             = 1,
        .dev = {
                .dma_mask       = &mmc1_dmamask,
-               .platform_data  = &mmc1_conf,
+               .platform_data  = &mmc1_data,
        },
        .num_resources  = ARRAY_SIZE(mmc1_resources),
        .resource       = mmc1_resources,
 };
 
-#ifdef CONFIG_ARCH_OMAP16XX
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+       defined(CONFIG_ARCH_OMAP34XX)
 
-static struct omap_mmc_conf mmc2_conf;
+static struct omap_mmc_platform_data mmc2_data;
 
 static u64 mmc2_dmamask = 0xffffffff;
 
 static struct resource mmc2_resources[] = {
        {
                .start          = OMAP_MMC2_BASE,
-               .end            = OMAP_MMC2_BASE + 0x7f,
+               .end            = OMAP_MMC2_END,
                .flags          = IORESOURCE_MEM,
        },
        {
-               .start          = INT_1610_MMC2,
+               .start          = OMAP_MMC2_INT,
                .flags          = IORESOURCE_IRQ,
        },
 };
@@ -255,26 +270,19 @@ static struct platform_device mmc_omap_device2 = {
        .id             = 2,
        .dev = {
                .dma_mask       = &mmc2_dmamask,
-               .platform_data  = &mmc2_conf,
+               .platform_data  = &mmc2_data,
        },
        .num_resources  = ARRAY_SIZE(mmc2_resources),
        .resource       = mmc2_resources,
 };
 #endif
 
-static void __init omap_init_mmc(void)
+static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
 {
-       const struct omap_mmc_config    *mmc_conf;
-       const struct omap_mmc_conf      *mmc;
-
-       /* NOTE:  assumes MMC was never (wrongly) enabled */
-       mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
-       if (!mmc_conf)
+       if (cpu_is_omap2430() || cpu_is_omap34xx())
                return;
 
-       /* block 1 is always available and has just one pinout option */
-       mmc = &mmc_conf->mmc[0];
-       if (mmc->enabled) {
+       if (mmc_conf->mmc[0].enabled) {
                if (cpu_is_omap24xx()) {
                        omap_cfg_reg(H18_24XX_MMC_CMD);
                        omap_cfg_reg(H15_24XX_MMC_CLKI);
@@ -292,7 +300,7 @@ static void __init omap_init_mmc(void)
                                omap_cfg_reg(P20_1710_MMC_DATDIR0);
                        }
                }
-               if (mmc->wire4) {
+               if (mmc_conf->mmc[0].wire4) {
                        if (cpu_is_omap24xx()) {
                                omap_cfg_reg(H14_24XX_MMC_DAT1);
                                omap_cfg_reg(E19_24XX_MMC_DAT2);
@@ -303,25 +311,22 @@ static void __init omap_init_mmc(void)
                        } else {
                                omap_cfg_reg(MMC_DAT1);
                                /* NOTE:  DAT2 can be on W10 (here) or M15 */
-                               if (!mmc->nomux)
+                               if (!mmc_conf->mmc[0].nomux)
                                        omap_cfg_reg(MMC_DAT2);
                                omap_cfg_reg(MMC_DAT3);
                        }
                }
-               mmc1_conf = *mmc;
-               (void) platform_device_register(&mmc_omap_device1);
        }
 
 #ifdef CONFIG_ARCH_OMAP16XX
        /* block 2 is on newer chips, and has many pinout options */
-       mmc = &mmc_conf->mmc[1];
-       if (mmc->enabled) {
-               if (!mmc->nomux) {
+       if (mmc_conf->mmc[1].enabled) {
+               if (!mmc_conf->mmc[1].nomux) {
                        omap_cfg_reg(Y8_1610_MMC2_CMD);
                        omap_cfg_reg(Y10_1610_MMC2_CLK);
                        omap_cfg_reg(R18_1610_MMC2_CLKIN);
                        omap_cfg_reg(W8_1610_MMC2_DAT0);
-                       if (mmc->wire4) {
+                       if (mmc_conf->mmc[1].wire4) {
                                omap_cfg_reg(V8_1610_MMC2_DAT1);
                                omap_cfg_reg(W15_1610_MMC2_DAT2);
                                omap_cfg_reg(R10_1610_MMC2_DAT3);
@@ -337,14 +342,55 @@ static void __init omap_init_mmc(void)
                if (cpu_is_omap1710())
                        omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
                                     MOD_CONF_CTRL_1);
-               mmc2_conf = *mmc;
+       }
+#endif
+}
+
+static void __init omap_init_mmc(void)
+{
+       const struct omap_mmc_config    *mmc_conf;
+
+       /* NOTE:  assumes MMC was never (wrongly) enabled */
+       mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
+       if (!mmc_conf)
+               return;
+
+       omap_init_mmc_conf(mmc_conf);
+
+       if (mmc_conf->mmc[0].enabled) {
+               mmc1_data.conf = mmc_conf->mmc[0];
+               (void) platform_device_register(&mmc_omap_device1);
+       }
+
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+       defined(CONFIG_ARCH_OMAP34XX)
+       if (mmc_conf->mmc[1].enabled) {
+               mmc2_data.conf = mmc_conf->mmc[1];
                (void) platform_device_register(&mmc_omap_device2);
        }
 #endif
-       return;
 }
+
+void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info)
+{
+       switch (host) {
+       case 1:
+               mmc1_data = *info;
+               break;
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+       defined(CONFIG_ARCH_OMAP34XX)
+       case 2:
+               mmc2_data = *info;
+               break;
+#endif
+       default:
+               BUG();
+       }
+}
+
 #else
 static inline void omap_init_mmc(void) {}
+void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
 #endif
 
 /*-------------------------------------------------------------------------*/
index ee4c292683e15a698656d22ba8068c89d5c9710b..dfc3443e23aa3df4cb0033c579a5f7a3d4679623 100644 (file)
@@ -325,7 +325,7 @@ static int __init atstk1002_init(void)
 #ifdef CONFIG_BOARD_ATSTK100X_SPI1
        at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
 #endif
-#ifndef CONFIG_BOARD_ATSTK1002_SW2_CUSTOM
+#ifndef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
        at32_add_device_mci(0, MCI_PDATA);
 #endif
 #ifdef CONFIG_BOARD_ATSTK1002_SW5_CUSTOM
diff --git a/arch/avr32/boot/images/.gitignore b/arch/avr32/boot/images/.gitignore
new file mode 100644 (file)
index 0000000..64ea9d0
--- /dev/null
@@ -0,0 +1,4 @@
+uImage
+uImage.srec
+vmlinux.cso
+sfdwarf.log
diff --git a/arch/avr32/kernel/.gitignore b/arch/avr32/kernel/.gitignore
new file mode 100644 (file)
index 0000000..c5f676c
--- /dev/null
@@ -0,0 +1 @@
+vmlinux.lds
index 84a7d44edc67e8acc981bb9b76343c747d76ab46..11e310c567a967bee5bb8ad31c13ed4c9a389cd8 100644 (file)
@@ -58,6 +58,7 @@ EXPORT_SYMBOL(find_first_zero_bit);
 EXPORT_SYMBOL(find_next_zero_bit);
 EXPORT_SYMBOL(find_first_bit);
 EXPORT_SYMBOL(find_next_bit);
+EXPORT_SYMBOL(generic_find_next_le_bit);
 EXPORT_SYMBOL(generic_find_next_zero_le_bit);
 
 /* I/O primitives (lib/io-*.S) */
index 890286a1e62b8c88147a4de13575814008a0e77c..673178e235f3a485005ecfd43415f86fad13ab9e 100644 (file)
@@ -109,3 +109,12 @@ __sys_epoll_pwait:
        rcall   sys_epoll_pwait
        sub     sp, -4
        popm    pc
+
+       .global __sys_sync_file_range
+       .type   __sys_sync_file_range,@function
+__sys_sync_file_range:
+       pushm   lr
+       st.w    --sp, ARG6
+       rcall   sys_sync_file_range
+       sub     sp, -4
+       popm    pc
index 478bda4c4a09a9ac57f119b4c8529d970cbc48e2..7ee0057613b3a70789663f604651bdbc319e2551 100644 (file)
@@ -275,7 +275,7 @@ sys_call_table:
        .long   sys_set_robust_list
        .long   sys_get_robust_list     /* 260 */
        .long   __sys_splice
-       .long   sys_sync_file_range
+       .long   __sys_sync_file_range
        .long   sys_tee
        .long   sys_vmsplice
        .long   __sys_epoll_pwait       /* 265 */
index b835c4c0136882e8320ddde56fe14d98d3f1201c..0d987373bc01b6b6424824711903b501294776da 100644 (file)
@@ -116,15 +116,15 @@ asmlinkage void do_nmi(unsigned long ecr, struct pt_regs *regs)
        switch (ret) {
        case NOTIFY_OK:
        case NOTIFY_STOP:
-               return;
+               break;
        case NOTIFY_BAD:
                die("Fatal Non-Maskable Interrupt", regs, SIGINT);
        default:
+               printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n");
+               nmi_disable();
                break;
        }
-
-       printk(KERN_ALERT "Got NMI, but nobody cared. Disabling...\n");
-       nmi_disable();
+       nmi_exit();
 }
 
 asmlinkage void do_critical_exception(unsigned long ecr, struct pt_regs *regs)
index c6b91dee857c822c507764e1c2a054a3ee02a5ba..997b33b2288a6989aa3bdac94b0417967d7f6208 100644 (file)
@@ -123,6 +123,36 @@ ENTRY(find_next_bit)
        brgt    1b
        retal   r11
 
+ENTRY(generic_find_next_le_bit)
+       lsr     r8, r10, 5
+       sub     r9, r11, r10
+       retle   r11
+
+       lsl     r8, 2
+       add     r12, r8
+       andl    r10, 31, COH
+       breq    1f
+
+       /* offset is not word-aligned. Handle the first (32 - r10) bits */
+       ldswp.w r8, r12[0]
+       sub     r12, -4
+       lsr     r8, r8, r10
+       brne    .L_found
+
+       /* r9 = r9 - (32 - r10) = r9 + r10 - 32 */
+       add     r9, r10
+       sub     r9, 32
+       retle   r11
+
+       /* Main loop. offset must be word-aligned */
+1:     ldswp.w r8, r12[0]
+       cp.w    r8, 0
+       brne    .L_found
+       sub     r12, -4
+       sub     r9, 32
+       brgt    1b
+       retal   r11
+
 ENTRY(generic_find_next_zero_le_bit)
        lsr     r8, r10, 5
        sub     r9, r11, r10
index 5e0c1a6bce8dea81ef7c8df40855de065a655eca..2acb6b6543c914c6293331623ed77a956918340a 100644 (file)
@@ -266,4 +266,19 @@ do {                                                                       \
        }                                                               \
 } while (0)
 
+/*
+ * format for entries in the Global Offset Table
+ */
+struct got_entry {
+       uint64_t val;
+};
+
+/*
+ * Layout of the Function Descriptor
+ */
+struct fdesc {
+       uint64_t ip;
+       uint64_t gp;
+};
+
 #endif /* _ASM_IA64_ELF_H */
index 7286e4a9fe8449e1b02e5e762eb9dc7e1aeb53ce..f6679989103689c24f01315b8f1e41c078b79ce2 100644 (file)
@@ -6,6 +6,8 @@
  *     David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
+#include <linux/elf.h>
+#include <linux/uaccess.h>
 #include <asm-generic/sections.h>
 
 extern char __per_cpu_start[], __per_cpu_end[], __phys_per_cpu_start[];
@@ -21,5 +23,17 @@ extern char __start_gate_brl_fsys_bubble_down_patchlist[], __end_gate_brl_fsys_b
 extern char __start_unwind[], __end_unwind[];
 extern char __start_ivt_text[], __end_ivt_text[];
 
+#undef dereference_function_descriptor
+static inline void *dereference_function_descriptor(void *ptr)
+{
+       struct fdesc *desc = ptr;
+       void *p;
+
+       if (!probe_kernel_address(&desc->ip, p))
+               ptr = p;
+       return ptr;
+}
+
+
 #endif /* _ASM_IA64_SECTIONS_H */
 
index a0d214f4311560cf100b4f568d78998f4a62b112..5efecf06c9a42efef99870084a3748e9bd3dfc15 100644 (file)
@@ -223,10 +223,11 @@ extern void bte_error_handler(unsigned long);
  * until the transfer is complete.  In order to get the asynch
  * version of bte_copy, you must perform this check yourself.
  */
-#define BTE_UNALIGNED_COPY(src, dest, len, mode)                        \
-       (((len & L1_CACHE_MASK) || (src & L1_CACHE_MASK) ||             \
-         (dest & L1_CACHE_MASK)) ?                                     \
-        bte_unaligned_copy(src, dest, len, mode) :                     \
+#define BTE_UNALIGNED_COPY(src, dest, len, mode)                       \
+       (((len & (L1_CACHE_BYTES - 1)) ||                               \
+         (src & (L1_CACHE_BYTES - 1)) ||                               \
+         (dest & (L1_CACHE_BYTES - 1))) ?                              \
+        bte_unaligned_copy(src, dest, len, mode) :                     \
         bte_copy(src, dest, len, mode, NULL))
 
 
index d45f215bc8fce2ee175d018c8298a506437eb0be..51b75cea701866629449f7945ddef10079faa7ab 100644 (file)
@@ -1232,9 +1232,10 @@ efi_initialize_iomem_resources(struct resource *code_resource,
                                if (md->attribute & EFI_MEMORY_WP) {
                                        name = "System ROM";
                                        flags |= IORESOURCE_READONLY;
-                               } else {
+                               } else if (md->attribute == EFI_MEMORY_UC)
+                                       name = "Uncached RAM";
+                               else
                                        name = "System RAM";
-                               }
                                break;
 
                        case EFI_ACPI_MEMORY_NVS:
index 29aad349e0c4fafd49eb6b8c07bce2f3db3a24d6..aaa7d901521fd7590e3132a68b65ffd995197551 100644 (file)
@@ -135,15 +135,6 @@ static const char *reloc_name[256] = {
 
 #undef N
 
-struct got_entry {
-       uint64_t val;
-};
-
-struct fdesc {
-       uint64_t ip;
-       uint64_t gp;
-};
-
 /* Opaque struct for insns, to protect against derefs. */
 struct insn;
 
index c27d5b2c182b4c7edd4de5609ce2a2c856a55ddb..de636b215677e801c23076d74f6d5a2d29e68efb 100644 (file)
@@ -616,7 +616,9 @@ setup_arch (char **cmdline_p)
                ia64_mca_init();
 
        platform_setup(cmdline_p);
+#ifndef CONFIG_IA64_HP_SIM
        check_sal_cache_flush();
+#endif
        paging_init();
 }
 
index bcea81e432fd79c6b9aa08407367e523cc0f41bd..d8f05e504fbf039bb85fa946c40e6ff01349d26b 100644 (file)
@@ -741,16 +741,14 @@ int __cpu_disable(void)
                        return -EBUSY;
        }
 
-       cpu_clear(cpu, cpu_online_map);
-
        if (migrate_platform_irqs(cpu)) {
                cpu_set(cpu, cpu_online_map);
                return (-EBUSY);
        }
 
        remove_siblinginfo(cpu);
-       cpu_clear(cpu, cpu_online_map);
        fixup_irqs();
+       cpu_clear(cpu, cpu_online_map);
        local_flush_tlb_all();
        cpu_clear(cpu, cpu_callin_map);
        return 0;
index 7a37d06376be893799fa2bfdb30311251a3edbeb..cd0d1a7284b78afbe673424b4463d3f6463621de 100644 (file)
@@ -38,6 +38,7 @@
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
 #include <asm/tlb.h>
+#include <asm/elf.h>
 
 #include "misc.h"
 #include "vti.h"
@@ -61,12 +62,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = {
        { NULL }
 };
 
-
-struct fdesc{
-    unsigned long ip;
-    unsigned long gp;
-};
-
 static void kvm_flush_icache(unsigned long start, unsigned long len)
 {
        int l;
index 529462c01570437aafdc8c9198ad394b8904e238..79165122501c20b696b5334401d397809a8a456b 100644 (file)
@@ -420,8 +420,10 @@ tioca_dma_mapped(struct pci_dev *pdev, u64 paddr, size_t req_size)
                entry = find_next_zero_bit(map, mapsize, last_entry);
        }
 
-       if (entry > mapsize)
+       if (entry > mapsize) {
+               kfree(ca_dmamap);
                goto map_return;
+       }
 
        for (i = 0; i < entries; i++)
                set_bit(entry + i, map);
index a5f864c445b2fe1a28f511dd2c033e4430fc0814..f57113f1f892b091e7439ee18448459b6df25678 100644 (file)
@@ -216,10 +216,6 @@ config MEMORY_SIZE
        default "01000000" if PLAT_M32104UT
        default "00800000" if PLAT_OAKS32R
 
-config NOHIGHMEM
-       bool
-       default y
-
 config ARCH_DISCONTIGMEM_ENABLE
        bool "Internal RAM Support"
        depends on CHIP_M32700 || CHIP_M32102 || CHIP_VDEC2 || CHIP_OPSP || CHIP_M32104
@@ -410,11 +406,7 @@ config PCI_DIRECT
 source "drivers/pci/Kconfig"
 
 config ISA
-       bool "ISA support"
-       help
-         Find out whether you have ISA slots on your motherboard.  ISA is the
-         name of a bus system, i.e. the way the CPU talks to the other stuff
-         inside your box.  If you have ISA, say Y, otherwise N.
+       bool
 
 source "drivers/pcmcia/Kconfig"
 
index d4eaa2fd1818fea9b90e7c8bbdbe2bd7757ca99b..612d35b082a6826d59dda272612df7d295fa2e8c 100644 (file)
@@ -143,7 +143,7 @@ ret_from_intr:
        and3    r4, r4, #0x8000         ; check BSM bit
 #endif
        beqz    r4, resume_kernel
-ENTRY(resume_userspace)
+resume_userspace:
        DISABLE_INTERRUPTS(r4)          ; make sure we don't miss an interrupt
                                        ; setting need_resched or sigpending
                                        ; between sampling and the iret
index dab7436d7bbe85e2997c18b43b5082e4eece4255..40180778a5c723e069cfc96739a0600f10b6e02b 100644 (file)
@@ -29,7 +29,6 @@ __INITDATA
        .global _end
 ENTRY(stext)
 ENTRY(_stext)
-ENTRY(startup_32)
        /* Setup up the stack pointer */
        LDIMM   (r0, spi_stack_top)
        LDIMM   (r1, spu_stack_top)
index d0c5b0b7da2f0f571fa8e37c44b5f1a41ac5f363..2aeae4670098245f7072ca69b4e732955e4d25d5 100644 (file)
@@ -22,9 +22,6 @@
 #include <linux/module.h>
 #include <asm/uaccess.h>
 
-atomic_t irq_err_count;
-atomic_t irq_mis_count;
-
 /*
  * Generic, controller-independent functions:
  */
@@ -63,9 +60,6 @@ int show_interrupts(struct seq_file *p, void *v)
                seq_putc(p, '\n');
 skip:
                spin_unlock_irqrestore(&irq_desc[i].lock, flags);
-       } else if (i == NR_IRQS) {
-               seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
-               seq_printf(p, "MIS: %10u\n", atomic_read(&irq_mis_count));
        }
        return 0;
 }
index 16bcb189a38319c0831dc0dd6fc1fa505eedc64d..22624b51d4d3ecf3222ce82de0464719bb731d49 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/delay.h>
 #include <asm/irq.h>
 #include <asm/tlbflush.h>
+#include <asm/pgtable.h>
 
 /* platform dependent support */
 EXPORT_SYMBOL(boot_cpu_data);
@@ -65,6 +66,7 @@ EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(empty_zero_page);
 
 EXPORT_SYMBOL(_inb);
 EXPORT_SYMBOL(_inw);
index a689e2978b6e382bdad4f9fcd56fbf194a1ddb6f..5be4faaf5b1c49c03391bb298e6f83122d6d88ab 100644 (file)
@@ -35,8 +35,6 @@
 
 #include <linux/err.h>
 
-static int hlt_counter=0;
-
 /*
  * Return saved PC of a blocked thread.
  */
@@ -48,31 +46,16 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
 /*
  * Powermanagement idle function, if any..
  */
-void (*pm_idle)(void) = NULL;
-EXPORT_SYMBOL(pm_idle);
+static void (*pm_idle)(void) = NULL;
 
 void (*pm_power_off)(void) = NULL;
 EXPORT_SYMBOL(pm_power_off);
 
-void disable_hlt(void)
-{
-       hlt_counter++;
-}
-
-EXPORT_SYMBOL(disable_hlt);
-
-void enable_hlt(void)
-{
-       hlt_counter--;
-}
-
-EXPORT_SYMBOL(enable_hlt);
-
 /*
  * We use this is we don't have any better
  * idle routine..
  */
-void default_idle(void)
+static void default_idle(void)
 {
        /* M32R_FIXME: Please use "cpu_sleep" mode.  */
        cpu_relax();
@@ -260,15 +243,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long spu,
        return 0;
 }
 
-/*
- * Capture the user space registers if the task is not running (in user space)
- */
-int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
-{
-       /* M32R_FIXME */
-       return 1;
-}
-
 asmlinkage int sys_fork(unsigned long r0, unsigned long r1, unsigned long r2,
        unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6,
        struct pt_regs regs)
index 7577f971ea4e3360d37ced6a7fa5f5ef1c401cec..929e5c9d3ad9c6467a5b28d24cd039a9597f1bc0 100644 (file)
@@ -84,7 +84,7 @@ void smp_send_timer(void);
 void smp_ipi_timer_interrupt(struct pt_regs *);
 void smp_local_timer_interrupt(void);
 
-void send_IPI_allbutself(int, int);
+static void send_IPI_allbutself(int, int);
 static void send_IPI_mask(cpumask_t, int, int);
 unsigned long send_IPI_mask_phys(cpumask_t, int, int);
 
@@ -722,7 +722,7 @@ void smp_local_timer_interrupt(void)
  * ---------- --- --------------------------------------------------------
  *
  *==========================================================================*/
-void send_IPI_allbutself(int ipi_num, int try)
+static void send_IPI_allbutself(int ipi_num, int try)
 {
        cpumask_t cpumask;
 
index 994cc15563558b03cd8c6aef4deff3d74424779a..6ea017727cced935c638a876dc193e7ef4e3288e 100644 (file)
@@ -34,7 +34,6 @@
 #include <asm/hw_irq.h>
 
 #ifdef CONFIG_SMP
-extern void send_IPI_allbutself(int, int);
 extern void smp_local_timer_interrupt(void);
 #endif
 
@@ -188,7 +187,7 @@ static long last_rtc_update = 0;
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-irqreturn_t timer_interrupt(int irq, void *dev_id)
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
 {
 #ifndef CONFIG_SMP
        profile_tick(CPU_PROFILING);
@@ -228,7 +227,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
-struct irqaction irq0 = {
+static struct irqaction irq0 = {
        .handler = timer_interrupt,
        .flags = IRQF_DISABLED,
        .mask = CPU_MASK_NONE,
index 46159a4e644b81f8bf0191641ac4fecfc58b0f82..03b14e55cd894791ab25e25fb5bfbc8827baf140 100644 (file)
@@ -61,7 +61,7 @@ extern unsigned long  eit_vector[];
        ((unsigned long)func - (unsigned long)eit_vector - entry*4)/4 \
        + 0xff000000UL
 
-void   set_eit_vector_entries(void)
+static void set_eit_vector_entries(void)
 {
        extern void default_eit_handler(void);
        extern void system_call(void);
@@ -121,9 +121,9 @@ void __init trap_init(void)
        cpu_init();
 }
 
-int kstack_depth_to_print = 24;
+static int kstack_depth_to_print = 24;
 
-void show_trace(struct task_struct *task, unsigned long *stack)
+static void show_trace(struct task_struct *task, unsigned long *stack)
 {
        unsigned long addr;
 
@@ -224,7 +224,7 @@ bad:
        printk("\n");
 }
 
-DEFINE_SPINLOCK(die_lock);
+static DEFINE_SPINLOCK(die_lock);
 
 void die(const char * str, struct pt_regs * regs, long err)
 {
index 59bfc34e0d9f8aa86ded52d4145592af889aec1f..ced549be80f5e9055528918394caaeca6d04270f 100644 (file)
@@ -6,6 +6,7 @@
  */
 
 #include <linux/param.h>
+#include <linux/module.h>
 #ifdef CONFIG_SMP
 #include <linux/sched.h>
 #include <asm/current.h>
@@ -121,3 +122,4 @@ void __ndelay(unsigned long nsecs)
 {
        __const_udelay(nsecs * 0x00005);  /* 2**32 / 1000000000 (rounded up) */
 }
+EXPORT_SYMBOL(__ndelay);
index 8e2a0f5faf53bbedf56a44fda5d085ee57a68999..8bd61a640fc9dde53b4e92f5e9efe53fbd6d5507 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:00 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -166,10 +172,6 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_ZORRO_NAMES=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -183,6 +185,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -460,6 +466,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -470,6 +477,7 @@ CONFIG_BLK_DEV_IDE=y
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -489,8 +497,6 @@ CONFIG_BLK_DEV_GAYLE=y
 CONFIG_BLK_DEV_IDEDOUBLER=y
 CONFIG_BLK_DEV_BUDDHA=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -556,6 +562,7 @@ CONFIG_A2091_SCSI=y
 CONFIG_GVP11_SCSI=y
 CONFIG_SCSI_A4000T=y
 CONFIG_SCSI_ZORRO7XX=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -564,7 +571,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -573,13 +580,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -722,6 +725,7 @@ CONFIG_INPUT_M68K_BEEP=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -757,6 +761,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -768,8 +773,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -844,10 +851,6 @@ CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
 CONFIG_DMASOUND_PAULA=m
 CONFIG_DMASOUND=m
@@ -861,6 +864,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -899,6 +903,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -958,6 +963,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -980,7 +986,6 @@ CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -989,7 +994,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -1054,6 +1058,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1113,6 +1119,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1154,6 +1164,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index e2d511e2a1d1683c286d2d4645654c0a0b1bfd1a..c41b854c028425fda2c4ffda83f892c78038de98 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:01 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -161,10 +167,6 @@ CONFIG_HEARTBEAT=y
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -178,6 +180,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -411,6 +414,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -430,7 +434,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -448,6 +454,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -499,6 +506,7 @@ CONFIG_SCSI_SRP_TGT_ATTRS=y
 CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -507,7 +515,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -516,13 +524,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -532,7 +536,6 @@ CONFIG_VETH=m
 # CONFIG_PHYLIB is not set
 CONFIG_NET_ETHERNET=y
 # CONFIG_MII is not set
-CONFIG_APOLLO_ELPLUS=y
 # CONFIG_IBM_NEW_EMAC_ZMII is not set
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
@@ -627,6 +630,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -657,6 +661,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -668,8 +673,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -738,10 +745,6 @@ CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -753,6 +756,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -789,6 +793,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -848,6 +853,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -860,18 +866,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -880,7 +885,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -944,6 +948,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1003,6 +1009,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1044,6 +1054,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 6e20d656adafe0605b34df01b68cc115076a5bfa..654c5acb9e86ea9fc0a2e748e8c4192231eacc1a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:02 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -162,10 +168,6 @@ CONFIG_HEARTBEAT=y
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -179,6 +181,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -409,6 +412,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -428,7 +432,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -452,6 +458,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -462,6 +469,7 @@ CONFIG_BLK_DEV_IDE=y
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -479,8 +487,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_FALCON_IDE=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -530,6 +536,7 @@ CONFIG_ISCSI_TCP=m
 CONFIG_ATARI_SCSI=y
 # CONFIG_ATARI_SCSI_TOSHIBA_DELAY is not set
 # CONFIG_ATARI_SCSI_RESET_BOOT is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -538,7 +545,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -547,13 +554,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -666,6 +669,7 @@ CONFIG_SERIO_LIBPS2=y
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -700,6 +704,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -711,8 +716,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -782,10 +789,6 @@ CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
 CONFIG_DMASOUND_ATARI=m
 CONFIG_DMASOUND=m
@@ -799,6 +802,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -806,11 +810,8 @@ CONFIG_HIDRAW=y
 # Character devices
 #
 CONFIG_ATARI_MFPSER=m
-CONFIG_ATARI_SCC=y
-CONFIG_ATARI_SCC_DMA=y
 CONFIG_ATARI_MIDI=m
 CONFIG_ATARI_DSP56K=m
-# CONFIG_SERIAL_CONSOLE is not set
 
 #
 # File systems
@@ -820,8 +821,10 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4DEV_FS=y
+# CONFIG_EXT4DEV_FS_XATTR is not set
 CONFIG_JBD=y
+CONFIG_JBD2=y
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
@@ -840,6 +843,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -899,6 +903,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -920,7 +925,6 @@ CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
-CONFIG_SUNRPC_BIND34=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -929,7 +933,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -994,6 +997,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1053,6 +1058,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1094,6 +1103,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index a0a9b30bb5022845d3bd2a6da0ce9adf71bacd41..2e44af0fe54a16b59eed806776384f8efbf6f406 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:03 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@ CONFIG_BINFMT_MISC=m
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -450,6 +456,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -503,6 +510,7 @@ CONFIG_ISCSI_TCP=m
 CONFIG_53C700_BE_BUS=y
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_BVME6000_SCSI=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -511,7 +519,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -520,13 +528,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -631,6 +635,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -661,6 +666,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -672,8 +678,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -708,10 +716,6 @@ CONFIG_SSB_POSSIBLE=y
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -723,6 +727,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -759,6 +764,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -818,6 +824,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -830,18 +837,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -850,7 +856,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -915,6 +920,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -974,6 +981,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1015,6 +1026,7 @@ CONFIG_BITREVERSE=m
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=m
 # CONFIG_CRC7 is not set
index 6778041de262796df5ceb8273a7c1c0e5bcf4a64..3570fc89b089f15f157ea4e1b35c90e33614bf40 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:04 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -162,10 +168,6 @@ CONFIG_HEARTBEAT=y
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -179,6 +181,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -412,6 +415,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -431,7 +435,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -449,6 +455,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -500,6 +507,7 @@ CONFIG_SCSI_SRP_TGT_ATTRS=y
 CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -508,7 +516,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -517,13 +525,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -636,6 +640,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -666,6 +671,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -677,8 +683,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -747,10 +755,6 @@ CONFIG_LOGO=y
 # CONFIG_LOGO_LINUX_MONO is not set
 # CONFIG_LOGO_LINUX_VGA16 is not set
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -762,6 +766,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -796,6 +801,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -855,6 +861,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -867,18 +874,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -887,7 +893,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -951,6 +956,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1010,6 +1017,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1051,6 +1062,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 7cd37574034886daf20cd7c6b803c10b0857b2e9..db6e8822594a47896154e8ba45b1f2f82f4a57ab 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:06 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@ CONFIG_BINFMT_MISC=m
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -450,6 +456,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -460,6 +467,7 @@ CONFIG_BLK_DEV_IDE=y
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -477,8 +485,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_MAC_IDE=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -527,6 +533,7 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_MAC_SCSI=y
 CONFIG_SCSI_MAC_ESP=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -535,7 +542,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -544,9 +551,6 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_MACINTOSH_DRIVERS=y
@@ -559,7 +563,6 @@ CONFIG_ADB_CUDA=y
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -670,6 +673,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -700,6 +704,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -711,8 +716,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -784,10 +791,6 @@ CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_LOGO_MAC_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -799,6 +802,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -836,6 +840,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -895,6 +900,7 @@ CONFIG_HFSPLUS_FS=y
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -917,7 +923,6 @@ CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=m
 CONFIG_SUNRPC_GSS=m
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=m
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -926,7 +931,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -991,6 +995,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1050,6 +1056,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=m
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1091,6 +1101,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 0747fa3984dfe8b2c11333303d11034ade04fecc..1a806102b999234a669805e231dccc4d599db5ac 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:07 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -173,10 +179,6 @@ CONFIG_GENERIC_ISA_DMA=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
 CONFIG_ZORRO_NAMES=y
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -190,6 +192,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -427,6 +430,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -446,7 +450,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -476,6 +482,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -486,6 +493,7 @@ CONFIG_BLK_DEV_IDE=y
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -508,8 +516,6 @@ CONFIG_BLK_DEV_FALCON_IDE=y
 CONFIG_BLK_DEV_MAC_IDE=y
 CONFIG_BLK_DEV_Q40IDE=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -584,6 +590,7 @@ CONFIG_MVME147_SCSI=y
 CONFIG_MVME16x_SCSI=y
 CONFIG_BVME6000_SCSI=y
 CONFIG_SUN3X_ESP=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -592,7 +599,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -601,9 +608,6 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_MACINTOSH_DRIVERS=y
@@ -616,7 +620,6 @@ CONFIG_ADB_CUDA=y
 CONFIG_INPUT_ADBHID=y
 CONFIG_MAC_EMUMOUSEBTN=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -632,7 +635,6 @@ CONFIG_A2065=m
 CONFIG_HYDRA=m
 CONFIG_ZORRO8390=m
 CONFIG_APNE=m
-CONFIG_APOLLO_ELPLUS=y
 CONFIG_MAC8390=y
 CONFIG_MAC89x0=m
 CONFIG_MACSONIC=m
@@ -791,6 +793,7 @@ CONFIG_SERIO_LIBPS2=y
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -827,6 +830,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -838,8 +842,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -923,10 +929,6 @@ CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
 CONFIG_LOGO_MAC_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
 CONFIG_DMASOUND_ATARI=m
 CONFIG_DMASOUND_PAULA=m
@@ -942,6 +944,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 
@@ -949,8 +952,6 @@ CONFIG_HIDRAW=y
 # Character devices
 #
 CONFIG_ATARI_MFPSER=m
-CONFIG_ATARI_SCC=y
-CONFIG_ATARI_SCC_DMA=y
 CONFIG_ATARI_MIDI=m
 CONFIG_ATARI_DSP56K=m
 CONFIG_AMIGA_BUILTIN_SERIAL=y
@@ -972,8 +973,10 @@ CONFIG_EXT2_FS=y
 # CONFIG_EXT2_FS_XIP is not set
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4DEV_FS is not set
+CONFIG_EXT4DEV_FS=y
+# CONFIG_EXT4DEV_FS_XATTR is not set
 CONFIG_JBD=y
+CONFIG_JBD2=y
 CONFIG_REISERFS_FS=m
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
@@ -992,6 +995,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -1051,6 +1055,7 @@ CONFIG_HFSPLUS_FS=y
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -1063,18 +1068,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -1083,7 +1087,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -1152,6 +1155,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1211,6 +1216,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1252,6 +1261,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index e7a8246840b56fdd559cb18843cf22e161816d07..cacb5aef6a37e865c76caad27116f08539a30157 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:08 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@ CONFIG_BINFMT_MISC=m
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -450,6 +456,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -502,6 +509,7 @@ CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_MVME147_SCSI=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -510,7 +518,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -519,13 +527,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -630,6 +634,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -660,6 +665,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -671,8 +677,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -707,10 +715,6 @@ CONFIG_SSB_POSSIBLE=y
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -722,6 +726,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -758,6 +763,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -817,6 +823,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -829,18 +836,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -849,7 +855,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -914,6 +919,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -973,6 +980,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1014,6 +1025,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index ab536eb172bb5791b5e440acfff2bda0f3ee00f5..a183e25e348d2a93b7b9e0be16f977a64854848a 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:09 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@ CONFIG_BINFMT_MISC=m
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -413,6 +416,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -432,7 +436,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -450,6 +456,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -503,6 +510,7 @@ CONFIG_ISCSI_TCP=m
 CONFIG_53C700_BE_BUS=y
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_MVME16x_SCSI=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -511,7 +519,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -520,13 +528,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -631,6 +635,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -661,6 +666,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -672,8 +678,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -708,10 +716,6 @@ CONFIG_SSB_POSSIBLE=y
 # Console display driver support
 #
 CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -723,6 +727,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -760,6 +765,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -819,6 +825,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -831,18 +838,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -851,7 +857,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -916,6 +921,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -975,6 +982,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1016,6 +1027,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index e05be687b500b69aad0775353391c517ed62109d..72eaff0776b80ca5dcea68a7911d62054111f86d 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:10 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -163,10 +169,6 @@ CONFIG_ISA=y
 CONFIG_GENERIC_ISA_DMA=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -180,6 +182,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -410,6 +413,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -429,7 +433,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -448,6 +454,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -458,6 +465,7 @@ CONFIG_BLK_DEV_IDE=y
 #
 # Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
+CONFIG_IDE_ATAPI=y
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
 # CONFIG_IDEDISK_MULTI_MODE is not set
@@ -475,8 +483,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_BLK_DEV_PLATFORM is not set
 CONFIG_BLK_DEV_Q40IDE=y
 # CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
 
 #
 # SCSI device support
@@ -536,6 +542,7 @@ CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_T128 is not set
 # CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -544,7 +551,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -553,13 +560,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -680,6 +683,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -711,6 +715,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -722,8 +727,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -792,10 +799,6 @@ CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 CONFIG_SOUND=m
 CONFIG_DMASOUND_Q40=m
 CONFIG_DMASOUND=m
@@ -809,6 +812,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -843,6 +847,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -902,6 +907,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -924,7 +930,6 @@ CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -933,7 +938,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -997,6 +1001,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1056,6 +1062,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1097,6 +1107,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 296340d2b315379d459fb1c02671839cfa93364e..cb62b96d766ed5493b8bfc9806b31227be91b715 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:11 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -149,10 +155,6 @@ CONFIG_BINFMT_MISC=m
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -166,6 +168,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -399,6 +402,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -418,7 +422,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -436,6 +442,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -488,6 +495,7 @@ CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SUN3_SCSI=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -496,7 +504,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -505,13 +513,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -527,7 +531,6 @@ CONFIG_SUN3_82586=y
 # CONFIG_IBM_NEW_EMAC_RGMII is not set
 # CONFIG_IBM_NEW_EMAC_TAH is not set
 # CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_B44 is not set
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 
@@ -617,6 +620,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -647,19 +651,20 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
 # Sonics Silicon Backplane
 #
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB is not set
 
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -727,10 +732,6 @@ CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -776,6 +777,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -835,6 +837,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -847,18 +850,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -867,7 +869,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -932,6 +933,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -991,6 +994,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1032,6 +1039,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index 8d3a416c92bf775bd122cf5d2faeaf3fb856c35d..04b4363a70503d5fa50948cd678ed3d3f56dcaa2 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc4
-# Wed May 28 22:47:35 2008
+# Linux kernel version: 2.6.27-rc6
+# Wed Sep 10 09:02:12 2008
 #
 CONFIG_M68K=y
 CONFIG_MMU=y
@@ -52,7 +52,6 @@ CONFIG_SYSCTL=y
 # CONFIG_EMBEDDED is not set
 CONFIG_UID16=y
 CONFIG_SYSCTL_SYSCALL=y
-CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_KALLSYMS=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_HOTPLUG=y
@@ -75,10 +74,16 @@ CONFIG_SLAB=y
 # CONFIG_PROFILING is not set
 # CONFIG_MARKERS is not set
 # CONFIG_HAVE_OPROFILE is not set
+# CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS is not set
+# CONFIG_HAVE_IOREMAP_PROT is not set
 # CONFIG_HAVE_KPROBES is not set
 # CONFIG_HAVE_KRETPROBES is not set
+# CONFIG_HAVE_ARCH_TRACEHOOK is not set
 # CONFIG_HAVE_DMA_ATTRS is not set
+# CONFIG_USE_GENERIC_SMP_HELPERS is not set
+# CONFIG_HAVE_CLK is not set
 CONFIG_PROC_PAGE_MONITOR=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
@@ -95,6 +100,7 @@ CONFIG_BLOCK=y
 # CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_LSF is not set
 CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
 
 #
 # IO Schedulers
@@ -160,10 +166,6 @@ CONFIG_BINFMT_MISC=m
 CONFIG_PROC_HARDWARE=y
 CONFIG_ZONE_DMA=y
 # CONFIG_ARCH_SUPPORTS_MSI is not set
-
-#
-# Networking
-#
 CONFIG_NET=y
 
 #
@@ -177,6 +179,7 @@ CONFIG_XFRM=y
 # CONFIG_XFRM_SUB_POLICY is not set
 CONFIG_XFRM_MIGRATE=y
 # CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=m
 CONFIG_NET_KEY=y
 CONFIG_NET_KEY_MIGRATE=y
 CONFIG_INET=y
@@ -410,6 +413,7 @@ CONFIG_NET_CLS_ROUTE=y
 #
 # CONFIG_CFG80211 is not set
 CONFIG_WIRELESS_EXT=y
+# CONFIG_WIRELESS_EXT_SYSFS is not set
 # CONFIG_MAC80211 is not set
 CONFIG_IEEE80211=m
 # CONFIG_IEEE80211_DEBUG is not set
@@ -429,7 +433,9 @@ CONFIG_IEEE80211_CRYPT_TKIP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_STANDALONE=y
 CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
 # CONFIG_SYS_HYPERVISOR is not set
 CONFIG_CONNECTOR=m
 # CONFIG_MTD is not set
@@ -447,6 +453,7 @@ CONFIG_CDROM_PKTCDVD=m
 CONFIG_CDROM_PKTCDVD_BUFFERS=8
 # CONFIG_CDROM_PKTCDVD_WCACHE is not set
 CONFIG_ATA_OVER_ETH=m
+# CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -499,6 +506,7 @@ CONFIG_SCSI_LOWLEVEL=y
 CONFIG_ISCSI_TCP=m
 # CONFIG_SCSI_DEBUG is not set
 CONFIG_SUN3X_ESP=y
+# CONFIG_SCSI_DH is not set
 CONFIG_MD=y
 CONFIG_BLK_DEV_MD=m
 CONFIG_MD_LINEAR=m
@@ -507,7 +515,7 @@ CONFIG_MD_RAID1=m
 # CONFIG_MD_RAID10 is not set
 CONFIG_MD_RAID456=m
 CONFIG_MD_RAID5_RESHAPE=y
-CONFIG_MD_MULTIPATH=m
+# CONFIG_MD_MULTIPATH is not set
 # CONFIG_MD_FAULTY is not set
 CONFIG_BLK_DEV_DM=m
 # CONFIG_DM_DEBUG is not set
@@ -516,13 +524,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
-CONFIG_DM_MULTIPATH_EMC=m
-CONFIG_DM_MULTIPATH_RDAC=m
-CONFIG_DM_MULTIPATH_HP=m
 # CONFIG_DM_DELAY is not set
 CONFIG_DM_UEVENT=y
 CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
 CONFIG_DUMMY=m
 # CONFIG_BONDING is not set
 CONFIG_MACVLAN=m
@@ -627,6 +631,7 @@ CONFIG_SERIO_LIBPS2=m
 # Character devices
 #
 CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
 CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
@@ -657,6 +662,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_POWER_SUPPLY is not set
 # CONFIG_HWMON is not set
 # CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -668,8 +674,10 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multifunction device drivers
 #
+# CONFIG_MFD_CORE is not set
 # CONFIG_MFD_SM501 is not set
 # CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
 
 #
 # Multimedia devices
@@ -737,10 +745,6 @@ CONFIG_LOGO=y
 CONFIG_LOGO_LINUX_MONO=y
 CONFIG_LOGO_LINUX_VGA16=y
 CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
 # CONFIG_SOUND is not set
 CONFIG_HID_SUPPORT=y
 CONFIG_HID=m
@@ -752,6 +756,7 @@ CONFIG_HIDRAW=y
 # CONFIG_NEW_LEDS is not set
 # CONFIG_ACCESSIBILITY is not set
 # CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
 # CONFIG_UIO is not set
 
 #
@@ -786,6 +791,7 @@ CONFIG_XFS_FS=m
 CONFIG_OCFS2_FS=m
 CONFIG_OCFS2_FS_O2CB=m
 CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m
+# CONFIG_OCFS2_FS_STATS is not set
 # CONFIG_OCFS2_DEBUG_MASKLOG is not set
 # CONFIG_OCFS2_DEBUG_FS is not set
 CONFIG_DNOTIFY=y
@@ -845,6 +851,7 @@ CONFIG_HFSPLUS_FS=m
 CONFIG_CRAMFS=m
 # CONFIG_VXFS_FS is not set
 CONFIG_MINIX_FS=y
+# CONFIG_OMFS_FS is not set
 CONFIG_HPFS_FS=m
 # CONFIG_QNX4FS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -857,18 +864,17 @@ CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
 # CONFIG_NFS_V3_ACL is not set
 CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
 CONFIG_NFSD=m
 CONFIG_NFSD_V3=y
 # CONFIG_NFSD_V3_ACL is not set
 # CONFIG_NFSD_V4 is not set
-CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_EXPORTFS=m
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC_GSS=y
-CONFIG_SUNRPC_BIND34=y
 CONFIG_RPCSEC_GSS_KRB5=y
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 CONFIG_SMB_FS=m
@@ -877,7 +883,6 @@ CONFIG_SMB_NLS_REMOTE="cp437"
 # CONFIG_CIFS is not set
 # CONFIG_NCP_FS is not set
 CONFIG_CODA_FS=m
-# CONFIG_CODA_FS_OLD_API is not set
 # CONFIG_AFS_FS is not set
 
 #
@@ -942,6 +947,8 @@ CONFIG_MAGIC_SYSRQ=y
 # CONFIG_HEADERS_CHECK is not set
 # CONFIG_DEBUG_KERNEL is not set
 CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_SAMPLES is not set
 
 #
@@ -1001,6 +1008,10 @@ CONFIG_CRYPTO_CRC32C=m
 CONFIG_CRYPTO_MD4=m
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=m
 CONFIG_CRYPTO_SHA256=m
 CONFIG_CRYPTO_SHA512=m
@@ -1042,6 +1053,7 @@ CONFIG_BITREVERSE=y
 # CONFIG_GENERIC_FIND_NEXT_BIT is not set
 CONFIG_CRC_CCITT=m
 CONFIG_CRC16=m
+CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
 CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
index b485d94ce8a5055d4e28b35f8dec1c7fc3b2af9e..e660ddd611c465dc6665ecf7d1346f82a5e77b98 100644 (file)
@@ -48,7 +48,7 @@ static void au1xxx_gpio2_write(unsigned gpio, int value)
 {
        gpio -= AU1XXX_GPIO_BASE;
 
-       gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | (value << gpio);
+       gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
 }
 
 static int au1xxx_gpio2_direction_input(unsigned gpio)
@@ -61,7 +61,8 @@ static int au1xxx_gpio2_direction_input(unsigned gpio)
 static int au1xxx_gpio2_direction_output(unsigned gpio, int value)
 {
        gpio -= AU1XXX_GPIO_BASE;
-       gpio2->dir = (0x01 << gpio) | (value << gpio);
+       gpio2->dir |= 0x01 << gpio;
+       gpio2->output = (GPIO2_OUTPUT_ENABLE_MASK << gpio) | ((!!value) << gpio);
        return 0;
 }
 
@@ -90,6 +91,7 @@ static int au1xxx_gpio1_direction_input(unsigned gpio)
 static int au1xxx_gpio1_direction_output(unsigned gpio, int value)
 {
        gpio1->trioutclr = (0x01 & gpio);
+       au1xxx_gpio1_write(gpio, value);
        return 0;
 }
 
index 335a6ae3d594044fa0ca99e44ee189631238b609..11c92dc53791bc2d6b62c727c09fe48cc032a7de 100644 (file)
@@ -45,18 +45,7 @@ static void r39xx_wait(void)
        local_irq_enable();
 }
 
-/*
- * There is a race when WAIT instruction executed with interrupt
- * enabled.
- * But it is implementation-dependent wheter the pipelie restarts when
- * a non-enabled interrupt is requested.
- */
-static void r4k_wait(void)
-{
-       __asm__("       .set    mips3                   \n"
-               "       wait                            \n"
-               "       .set    mips0                   \n");
-}
+extern void r4k_wait(void);
 
 /*
  * This variant is preferable as it allows testing need_resched and going to
@@ -128,7 +117,7 @@ static int __init wait_disable(char *s)
 
 __setup("nowait", wait_disable);
 
-static inline void check_wait(void)
+void __init check_wait(void)
 {
        struct cpuinfo_mips *c = &current_cpu_data;
 
@@ -242,7 +231,6 @@ static inline void check_errata(void)
 
 void __init check_bugs32(void)
 {
-       check_wait();
        check_errata();
 }
 
index c6ada98ee042039a968e57d57f800ee1c8313ed6..f886dd7f708e1d13f833fce5db545b737f15e684 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/stackframe.h>
 #include <asm/war.h>
 #include <asm/page.h>
+#include <asm/thread_info.h>
 
 #define PANIC_PIC(msg)                                 \
                .set push;                              \
@@ -126,7 +127,42 @@ handle_vcei:
 
        __FINIT
 
+       .align  5       /* 32 byte rollback region */
+LEAF(r4k_wait)
+       .set    push
+       .set    noreorder
+       /* start of rollback region */
+       LONG_L  t0, TI_FLAGS($28)
+       nop
+       andi    t0, _TIF_NEED_RESCHED
+       bnez    t0, 1f
+        nop
+       nop
+       nop
+       .set    mips3
+       wait
+       /* end of rollback region (the region size must be power of two) */
+       .set    pop
+1:
+       jr      ra
+       END(r4k_wait)
+
+       .macro  BUILD_ROLLBACK_PROLOGUE handler
+       FEXPORT(rollback_\handler)
+       .set    push
+       .set    noat
+       MFC0    k0, CP0_EPC
+       PTR_LA  k1, r4k_wait
+       ori     k0, 0x1f        /* 32 byte rollback region */
+       xori    k0, 0x1f
+       bne     k0, k1, 9f
+       MTC0    k0, CP0_EPC
+9:
+       .set pop
+       .endm
+
        .align  5
+BUILD_ROLLBACK_PROLOGUE handle_int
 NESTED(handle_int, PT_SIZE, sp)
 #ifdef CONFIG_TRACE_IRQFLAGS
        /*
@@ -201,6 +237,7 @@ NESTED(except_vec_ejtag_debug, 0, sp)
  * This prototype is copied to ebase + n*IntCtl.VS and patched
  * to invoke the handler
  */
+BUILD_ROLLBACK_PROLOGUE except_vec_vi
 NESTED(except_vec_vi, 0, sp)
        SAVE_SOME
        SAVE_AT
index 8f6d58ede33cea5f42424fb27becd432e7b1f7b3..6e152c80cd4a5bb3d0a73816311a850181371b81 100644 (file)
@@ -236,8 +236,7 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
 
                atomic_set(&kgdb_cpu_doing_single_step, -1);
                if (remcom_in_buffer[0] == 's')
-                       if (kgdb_contthread)
-                               atomic_set(&kgdb_cpu_doing_single_step, cpu);
+                       atomic_set(&kgdb_cpu_doing_single_step, cpu);
 
                return 0;
        }
index b16facd9ea8ecae7b27116952090beca25450c78..ce7684335a415fb98de1781058d9db9f6d5271eb 100644 (file)
@@ -148,6 +148,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
        clear_tsk_thread_flag(p, TIF_USEDFPU);
 
 #ifdef CONFIG_MIPS_MT_FPAFF
+       clear_tsk_thread_flag(p, TIF_FPUBOUND);
+
        /*
         * FPU affinity support is cleaner if we track the
         * user-visible CPU affinity from the very beginning.
index 6bee29097a565e71459f80ee75c3affd3d0ed25b..5fd0cd020af58e3f2fa5c3753be3098e710ba109 100644 (file)
@@ -46,6 +46,9 @@
 #include <asm/types.h>
 #include <asm/stacktrace.h>
 
+extern void check_wait(void);
+extern asmlinkage void r4k_wait(void);
+extern asmlinkage void rollback_handle_int(void);
 extern asmlinkage void handle_int(void);
 extern asmlinkage void handle_tlbm(void);
 extern asmlinkage void handle_tlbl(void);
@@ -1251,6 +1254,9 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
 
                extern char except_vec_vi, except_vec_vi_lui;
                extern char except_vec_vi_ori, except_vec_vi_end;
+               extern char rollback_except_vec_vi;
+               char *vec_start = (cpu_wait == r4k_wait) ?
+                       &rollback_except_vec_vi : &except_vec_vi;
 #ifdef CONFIG_MIPS_MT_SMTC
                /*
                 * We need to provide the SMTC vectored interrupt handler
@@ -1258,11 +1264,11 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                 * Status.IM bit to be masked before going there.
                 */
                extern char except_vec_vi_mori;
-               const int mori_offset = &except_vec_vi_mori - &except_vec_vi;
+               const int mori_offset = &except_vec_vi_mori - vec_start;
 #endif /* CONFIG_MIPS_MT_SMTC */
-               const int handler_len = &except_vec_vi_end - &except_vec_vi;
-               const int lui_offset = &except_vec_vi_lui - &except_vec_vi;
-               const int ori_offset = &except_vec_vi_ori - &except_vec_vi;
+               const int handler_len = &except_vec_vi_end - vec_start;
+               const int lui_offset = &except_vec_vi_lui - vec_start;
+               const int ori_offset = &except_vec_vi_ori - vec_start;
 
                if (handler_len > VECTORSPACING) {
                        /*
@@ -1272,7 +1278,7 @@ static void *set_vi_srs_handler(int n, vi_handler_t addr, int srs)
                        panic("VECTORSPACING too small");
                }
 
-               memcpy(b, &except_vec_vi, handler_len);
+               memcpy(b, vec_start, handler_len);
 #ifdef CONFIG_MIPS_MT_SMTC
                BUG_ON(n > 7);  /* Vector index %d exceeds SMTC maximum. */
 
@@ -1554,6 +1560,10 @@ void __init trap_init(void)
        extern char except_vec3_generic, except_vec3_r4000;
        extern char except_vec4;
        unsigned long i;
+       int rollback;
+
+       check_wait();
+       rollback = (cpu_wait == r4k_wait);
 
 #if defined(CONFIG_KGDB)
        if (kgdb_early_setup)
@@ -1618,7 +1628,7 @@ void __init trap_init(void)
        if (board_be_init)
                board_be_init();
 
-       set_except_vector(0, handle_int);
+       set_except_vector(0, rollback ? rollback_handle_int : handle_int);
        set_except_vector(1, handle_tlbm);
        set_except_vector(2, handle_tlbl);
        set_except_vector(3, handle_tlbs);
index b5470ceb418b301847f385d72e306eff0b1bf6dc..afb119f35682680c2eb5eeddb20137aab7e64aa9 100644 (file)
@@ -36,6 +36,7 @@ SECTIONS
                SCHED_TEXT
                LOCK_TEXT
                KPROBES_TEXT
+               *(.text.*)
                *(.fixup)
                *(.gnu.warning)
        } :text = 0
index 8d7784122c143b7a36689d82dbe057928244a355..edac9892c51a19a5e8084ad26ca5584d54c78499 100644 (file)
 #ifdef USE_DOUBLE
 
 #define LOAD   ld
+#define LOAD32 lwu
 #define ADD    daddu
 #define NBYTES 8
 
 #else
 
 #define LOAD   lw
+#define LOAD32 lw
 #define ADD    addu
 #define NBYTES 4
 
        ADD     sum, v1;                                        \
        .set    pop
 
+#define ADDC32(sum,reg)                                                \
+       .set    push;                                           \
+       .set    noat;                                           \
+       addu    sum, reg;                                       \
+       sltu    v1, sum, reg;                                   \
+       addu    sum, v1;                                        \
+       .set    pop
+
 #define CSUM_BIGCHUNK1(src, offset, sum, _t0, _t1, _t2, _t3)   \
        LOAD    _t0, (offset + UNIT(0))(src);                   \
        LOAD    _t1, (offset + UNIT(1))(src);                   \
@@ -132,7 +142,7 @@ LEAF(csum_partial)
        beqz    t8, .Lqword_align
         andi   t8, src, 0x8
 
-       lw      t0, 0x00(src)
+       LOAD32  t0, 0x00(src)
        LONG_SUBU       a1, a1, 0x4
        ADDC(sum, t0)
        PTR_ADDU        src, src, 0x4
@@ -211,7 +221,7 @@ LEAF(csum_partial)
        LONG_SRL        t8, t8, 0x2
 
 .Lend_words:
-       lw      t0, (src)
+       LOAD32  t0, (src)
        LONG_SUBU       t8, t8, 0x1
        ADDC(sum, t0)
        .set    reorder                         /* DADDI_WAR */
@@ -230,6 +240,9 @@ LEAF(csum_partial)
        /* Still a full word to go  */
        ulw     t1, (src)
        PTR_ADDIU       src, 4
+#ifdef USE_DOUBLE
+       dsll    t1, t1, 32                      /* clear lower 32bit */
+#endif
        ADDC(sum, t1)
 
 1:     move    t1, zero
@@ -280,7 +293,7 @@ LEAF(csum_partial)
 1:
        .set    reorder
        /* Add the passed partial csum.  */
-       ADDC(sum, a2)
+       ADDC32(sum, a2)
        jr      ra
        .set    noreorder
        END(csum_partial)
@@ -681,7 +694,7 @@ EXC(        sb      t0, NBYTES-2(dst), .Ls_exc)
        .set    pop
 1:
        .set reorder
-       ADDC(sum, psum)
+       ADDC32(sum, psum)
        jr      ra
        .set noreorder
 
index 15e01aec37fdcab3e67e6e5d8390c925c138e20c..c8c32f417b6ce84c32087585456f6e78ae47e58b 100644 (file)
@@ -15,6 +15,7 @@ obj-$(CONFIG_SOC_TX3927)      += ops-tx3927.o
 obj-$(CONFIG_PCI_VR41XX)       += ops-vr41xx.o pci-vr41xx.o
 obj-$(CONFIG_MARKEINS)         += ops-emma2rh.o pci-emma2rh.o fixup-emma2rh.o
 obj-$(CONFIG_PCI_TX4927)       += ops-tx4927.o
+obj-$(CONFIG_BCM47XX)          += pci-bcm47xx.o
 
 #
 # These are still pretty much in the old state, watch, go blind.
diff --git a/arch/mips/pci/pci-bcm47xx.c b/arch/mips/pci/pci-bcm47xx.c
new file mode 100644 (file)
index 0000000..bea9b6c
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ *  Copyright (C) 2008 Aurelien Jarno <aurelien@aurel32.net>
+ *
+ *  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;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
+ *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
+ *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
+ *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
+ *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *  You should have received a copy of the  GNU General Public License along
+ *  with this program; if not, write  to the Free Software Foundation, Inc.,
+ *  675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/ssb/ssb.h>
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       return 0;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+       int res;
+       u8 slot, pin;
+
+       res = ssb_pcibios_plat_dev_init(dev);
+       if (res < 0) {
+               printk(KERN_ALERT "PCI: Failed to init device %s\n",
+                      pci_name(dev));
+               return res;
+       }
+
+       pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
+       slot = PCI_SLOT(dev->devfn);
+       res = ssb_pcibios_map_irq(dev, slot, pin);
+
+       /* IRQ-0 and IRQ-1 are software interrupts. */
+       if (res < 2) {
+               printk(KERN_ALERT "PCI: Failed to map IRQ of device %s\n",
+                      pci_name(dev));
+               return res;
+       }
+
+       dev->irq = res;
+       return 0;
+}
+
index bd78368c82bf2001a035a54bb9ff94942ba4cbd0..f97ab14610129bca9c2b696de7bd59f0dcb8d8f6 100644 (file)
@@ -142,26 +142,48 @@ int __cpuinit bridge_probe(nasid_t nasid, int widget_id, int masterwid)
  * on any one of the hubs connected to its xbow.
  */
 int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       return 0;
+}
+
+/* Most MIPS systems have straight-forward swizzling needs.  */
+static inline u8 bridge_swizzle(u8 pin, u8 slot)
+{
+       return (((pin - 1) + slot) % 4) + 1;
+}
+
+static inline struct pci_dev *bridge_root_dev(struct pci_dev *dev)
+{
+       while (dev->bus->parent) {
+               /* Move up the chain of bridges. */
+               dev = dev->bus->self;
+       }
+
+       return dev;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
 {
        struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
-       int irq = bc->pci_int[slot];
+       struct pci_dev *rdev = bridge_root_dev(dev);
+       int slot = PCI_SLOT(rdev->devfn);
+       int irq;
 
+       irq = bc->pci_int[slot];
        if (irq == -1) {
-               irq = bc->pci_int[slot] = request_bridge_irq(bc);
+               irq = request_bridge_irq(bc);
                if (irq < 0)
-                       panic("Can't allocate interrupt for PCI device %s\n",
-                             pci_name(dev));
+                       return irq;
+
+               bc->pci_int[slot] = irq;
        }
 
        irq_to_bridge[irq] = bc;
        irq_to_slot[irq] = slot;
 
-       return irq;
-}
+       dev->irq = irq;
 
-/* Do platform specific device initialization at pci_enable_device() time */
-int pcibios_plat_dev_init(struct pci_dev *dev)
-{
        return 0;
 }
 
index 60141235ec40a956162f6343b27d55d567f0d386..52486c4d2b019739be2db360e3cbc8b7dd1fd847 100644 (file)
@@ -150,7 +150,7 @@ static int __init sgiseeq_devinit(void)
                return res;
 
        /* Second HPC is missing? */
-       if (!ip22_is_fullhouse() ||
+       if (ip22_is_fullhouse() ||
            get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]))
                return 0;
 
index cba36a247e32b634e21e0e03e2c39c27aa4342ea..92dd1a0ca3523023a30d887067c9e280864cfce5 100644 (file)
@@ -72,6 +72,7 @@ static void irq_dispatch(unsigned int irq)
        cascade = irq_cascade + irq;
        if (cascade->get_irq != NULL) {
                unsigned int source_irq = irq;
+               int ret;
                desc = irq_desc + source_irq;
                if (desc->chip->mask_ack)
                        desc->chip->mask_ack(source_irq);
@@ -79,8 +80,9 @@ static void irq_dispatch(unsigned int irq)
                        desc->chip->mask(source_irq);
                        desc->chip->ack(source_irq);
                }
-               irq = cascade->get_irq(irq);
-               if (irq < 0)
+               ret = cascade->get_irq(irq);
+               irq = ret;
+               if (ret < 0)
                        atomic_inc(&irq_err_count);
                else
                        irq_dispatch(irq);
index babb7c2ac37701be5065da1e9cba3d1659cf636c..e4606586f94ce5e08d35720ca8b4f7512db4aa34 100644 (file)
@@ -1,6 +1,6 @@
 /* MN10300 Low level time management
  *
- * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Copyright (C) 2007-2008 Red Hat, Inc. All Rights Reserved.
  * Written by David Howells (dhowells@redhat.com)
  * - Derived from arch/i386/kernel/time.c
  *
@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/smp.h>
 #include <linux/profile.h>
+#include <linux/cnt32_to_63.h>
 #include <asm/irq.h>
 #include <asm/div64.h>
 #include <asm/processor.h>
@@ -40,27 +41,54 @@ static struct irqaction timer_irq = {
        .name           = "timer",
 };
 
+static unsigned long sched_clock_multiplier;
+
 /*
  * scheduler clock - returns current time in nanosec units.
  */
 unsigned long long sched_clock(void)
 {
        union {
-               unsigned long long l;
-               u32 w[2];
-       } quot;
+               unsigned long long ll;
+               unsigned l[2];
+       } tsc64, result;
+       unsigned long tsc, tmp;
+       unsigned product[3]; /* 96-bit intermediate value */
+
+       /* read the TSC value
+        */
+       tsc = 0 - get_cycles(); /* get_cycles() counts down */
 
-       quot.w[0] = mn10300_last_tsc - get_cycles();
-       quot.w[1] = 1000000000;
+       /* expand to 64-bits.
+        * - sched_clock() must be called once a minute or better or the
+        *   following will go horribly wrong - see cnt32_to_63()
+        */
+       tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL;
 
-       asm("mulu %2,%3,%0,%1"
-           : "=r"(quot.w[1]), "=r"(quot.w[0])
-           : "0"(quot.w[1]), "1"(quot.w[0])
+       /* scale the 64-bit TSC value to a nanosecond value via a 96-bit
+        * intermediate
+        */
+       asm("mulu       %2,%0,%3,%0     \n"     /* LSW * mult ->  0:%3:%0 */
+           "mulu       %2,%1,%2,%1     \n"     /* MSW * mult -> %2:%1:0 */
+           "add        %3,%1           \n"
+           "addc       0,%2            \n"     /* result in %2:%1:%0 */
+           : "=r"(product[0]), "=r"(product[1]), "=r"(product[2]), "=r"(tmp)
+           :  "0"(tsc64.l[0]),  "1"(tsc64.l[1]),  "2"(sched_clock_multiplier)
            : "cc");
 
-       do_div(quot.l, MN10300_TSCCLK);
+       result.l[0] = product[1] << 16 | product[0] >> 16;
+       result.l[1] = product[2] << 16 | product[1] >> 16;
 
-       return quot.l;
+       return result.ll;
+}
+
+/*
+ * initialise the scheduler clock
+ */
+static void __init mn10300_sched_clock_init(void)
+{
+       sched_clock_multiplier =
+               __muldiv64u(NSEC_PER_SEC, 1 << 16, MN10300_TSCCLK);
 }
 
 /*
@@ -128,4 +156,6 @@ void __init time_init(void)
        /* start the watchdog timer */
        watchdog_go();
 #endif
+
+       mn10300_sched_clock_init();
 }
index 78f092ca031626d5e22c2514ad225ce38e2530e1..33cf25025dac22f86dad42a8ebf8cef489db8779 100644 (file)
@@ -174,7 +174,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long fault_code,
         * If we're in an interrupt or have no user
         * context, we must not take the fault..
         */
-       if (in_interrupt() || !mm)
+       if (in_atomic() || !mm)
                goto no_context;
 
        down_read(&mm->mmap_sem);
index fdacdd4341c9f3ccf3189afe683b7179ead823d4..44138c3e6ea74e3042b2ddb66058714eb74bc27f 100644 (file)
@@ -47,7 +47,9 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/bug.h>
+#include <linux/uaccess.h>
 
+#include <asm/sections.h>
 #include <asm/unwind.h>
 
 #if 0
@@ -860,3 +862,15 @@ void module_arch_cleanup(struct module *mod)
        deregister_unwind_table(mod);
        module_bug_cleanup(mod);
 }
+
+#ifdef CONFIG_64BIT
+void *dereference_function_descriptor(void *ptr)
+{
+       Elf64_Fdesc *desc = ptr;
+       void *p;
+
+       if (!probe_kernel_address(&desc->addr, p))
+               ptr = p;
+       return ptr;
+}
+#endif
index 717a3bc1352e542d410e3713e2222e7ea2745516..65d1a8454d2cfb11e54ffa3082c16bc3316bd4da 100644 (file)
@@ -195,7 +195,7 @@ image-$(CONFIG_PPC_CELLEB)          += zImage.pseries
 image-$(CONFIG_PPC_CHRP)               += zImage.chrp
 image-$(CONFIG_PPC_EFIKA)              += zImage.chrp
 image-$(CONFIG_PPC_PMAC)               += zImage.pmac
-image-$(CONFIG_PPC_HOLLY)              += zImage.holly
+image-$(CONFIG_PPC_HOLLY)              += dtbImage.holly
 image-$(CONFIG_PPC_PRPMC2800)          += dtbImage.prpmc2800
 image-$(CONFIG_PPC_ISERIES)            += zImage.iseries
 image-$(CONFIG_DEFAULT_UIMAGE)         += uImage
index 3b3a1062cb250886e7d056169ab5e343afe14d5d..584a4f184eb26cddbac0d50c7feb52f406ab7e05 100644 (file)
                                cell-index = <0>;
                                reg = <0x0 0x80>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <60 2>;
+                               interrupts = <76 2>;
                        };
                        dma-channel@1 {
                                compatible = "fsl,mpc8610-dma-channel",
                                cell-index = <1>;
                                reg = <0x80 0x80>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <61 2>;
+                               interrupts = <77 2>;
                        };
                        dma-channel@2 {
                                compatible = "fsl,mpc8610-dma-channel",
                                cell-index = <2>;
                                reg = <0x100 0x80>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <62 2>;
+                               interrupts = <78 2>;
                        };
                        dma-channel@3 {
                                compatible = "fsl,mpc8610-dma-channel",
                                cell-index = <3>;
                                reg = <0x180 0x80>;
                                interrupt-parent = <&mpic>;
-                               interrupts = <63 2>;
+                               interrupts = <79 2>;
                        };
                };
 
index 80d1f399ee513a944aae0b7366a55d588393fac9..64c6ee22eefd6ba4cb6dd5da54bd801440111c2a 100644 (file)
@@ -409,6 +409,13 @@ do {                                                                       \
 /* Keep this the last entry.  */
 #define R_PPC64_NUM            107
 
+/* There's actually a third entry here, but it's unused */
+struct ppc64_opd_entry
+{
+       unsigned long funcaddr;
+       unsigned long r2;
+};
+
 #ifdef  __KERNEL__
 
 #ifdef CONFIG_SPU_BASE
index 916018e425c4dc7112f6c0c1f49f884118d4bd0b..07956f3e78444f5f63390d8d328c000af957061f 100644 (file)
@@ -2,6 +2,8 @@
 #define _ASM_POWERPC_SECTIONS_H
 #ifdef __KERNEL__
 
+#include <linux/elf.h>
+#include <linux/uaccess.h>
 #include <asm-generic/sections.h>
 
 #ifdef __powerpc64__
@@ -16,6 +18,17 @@ static inline int in_kernel_text(unsigned long addr)
        return 0;
 }
 
+#undef dereference_function_descriptor
+static inline void *dereference_function_descriptor(void *ptr)
+{
+       struct ppc64_opd_entry *desc = ptr;
+       void *p;
+
+       if (!probe_kernel_address(&desc->funcaddr, p))
+               ptr = p;
+       return ptr;
+}
+
 #endif
 
 #endif /* __KERNEL__ */
index b4fdf2f2743ca6cb7497bba075f80b9b413d01dc..fe8f71dd0b3f1bd711ca4a480cdcdc2943007c9f 100644 (file)
@@ -347,9 +347,8 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,
                        linux_regs->msr |= MSR_SE;
 #endif
                        kgdb_single_step = 1;
-                       if (kgdb_contthread)
-                               atomic_set(&kgdb_cpu_doing_single_step,
-                                          raw_smp_processor_id());
+                       atomic_set(&kgdb_cpu_doing_single_step,
+                                  raw_smp_processor_id());
                }
                return 0;
        }
index ee6a2982d567351eb88ace12c2109918af6af59e..1af2377e49929dc367d49b4588fd2ba6d23d7e91 100644 (file)
@@ -22,7 +22,6 @@
 #include <linux/vmalloc.h>
 #include <linux/bug.h>
 #include <asm/module.h>
-#include <asm/uaccess.h>
 #include <asm/firmware.h>
 #include <asm/code-patching.h>
 #include <linux/sort.h>
 #define DEBUGP(fmt , ...)
 #endif
 
-/* There's actually a third entry here, but it's unused */
-struct ppc64_opd_entry
-{
-       unsigned long funcaddr;
-       unsigned long r2;
-};
-
 /* Like PPC32, we need little trampolines to do > 24-bit jumps (into
    the kernel itself).  But on PPC64, these need to be used for every
    jump, actually, to reset r2 (TOC+0x8000). */
index 32e0ad0ebea8286af9b5b3b8cc1bd18ac1a42ed0..b6bd775d2e222d765e5bbad2e986c5d9ac19def3 100644 (file)
@@ -293,10 +293,8 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id,
                return -ENODEV;
 
        prop = of_get_property(phy, "reg", NULL);
-       if (prop) {
-               pdata.force_phy_addr = 1;
-               pdata.phy_addr = *prop;
-       }
+       if (prop)
+               pdata.phy_addr = MV643XX_ETH_PHY_ADDR(*prop);
 
        of_node_put(phy);
 
index cde81fa64f89bf17bc586dce3f973e77f55985e8..a2be3a978d5c43281e3cf3115e2dfb19d473307f 100644 (file)
@@ -42,6 +42,7 @@ struct user_regs_struct32
        u32 gprs[NUM_GPRS];
        u32 acrs[NUM_ACRS];
        u32 orig_gpr2;
+       /* nb: there's a 4-byte hole here */
        s390_fp_regs fp_regs;
        /*
         * These per registers are in here so that gdb can modify them
index 2815bfe348a6f92e67b64e04e0b70cbecde6bc58..c8b08289eb87e1d78c9c92996fe7bbfe30c16645 100644 (file)
@@ -170,6 +170,13 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr)
                 */
                tmp = (addr_t) task_pt_regs(child)->orig_gpr2;
 
+       } else if (addr < (addr_t) &dummy->regs.fp_regs) {
+               /*
+                * prevent reads of padding hole between
+                * orig_gpr2 and fp_regs on s390.
+                */
+               tmp = 0;
+
        } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
                /* 
                 * floating point regs. are stored in the thread structure
@@ -270,6 +277,13 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data)
                 */
                task_pt_regs(child)->orig_gpr2 = data;
 
+       } else if (addr < (addr_t) &dummy->regs.fp_regs) {
+               /*
+                * prevent writes of padding hole between
+                * orig_gpr2 and fp_regs on s390.
+                */
+               return 0;
+
        } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) {
                /*
                 * floating point regs. are stored in the thread structure
@@ -428,6 +442,13 @@ static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
                 */
                tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
 
+       } else if (addr < (addr_t) &dummy32->regs.fp_regs) {
+               /*
+                * prevent reads of padding hole between
+                * orig_gpr2 and fp_regs on s390.
+                */
+               tmp = 0;
+
        } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
                /*
                 * floating point regs. are stored in the thread structure 
@@ -514,6 +535,13 @@ static int __poke_user_compat(struct task_struct *child,
                 */
                *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
 
+       } else if (addr < (addr_t) &dummy32->regs.fp_regs) {
+               /*
+                * prevent writess of padding hole between
+                * orig_gpr2 and fp_regs on s390.
+                */
+               return 0;
+
        } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) {
                /*
                 * floating point regs. are stored in the thread structure 
index c481d45f97b748a3748c8fcc813be7d7965555e6..f58c537446a87547bafbbf396a42a65b2875c924 100644 (file)
@@ -241,7 +241,7 @@ static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna)
        return of_bus_default_map(addr, range, na, ns, pna);
 }
 
-static unsigned int of_bus_sbus_get_flags(const u32 *addr)
+static unsigned long of_bus_sbus_get_flags(const u32 *addr, unsigned long flags)
 {
        return IORESOURCE_MEM;
 }
index 20699c701412dc85506770375e94e3ccbe79efc5..8ce6285a06d55794b7a0ea68035ba65a0b39861e 100644 (file)
@@ -288,7 +288,7 @@ static const struct user_regset sparc32_regsets[] = {
         */
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
-               .n = 38 * sizeof(u32),
+               .n = 38,
                .size = sizeof(u32), .align = sizeof(u32),
                .get = genregs32_get, .set = genregs32_set
        },
@@ -304,7 +304,7 @@ static const struct user_regset sparc32_regsets[] = {
         */
        [REGSET_FP] = {
                .core_note_type = NT_PRFPREG,
-               .n = 99 * sizeof(u32),
+               .n = 99,
                .size = sizeof(u32), .align = sizeof(u32),
                .get = fpregs32_get, .set = fpregs32_set
        },
index 9b6689d9d57097239641d51653dc921e2607b997..7495bc774685d53df0385bebec0cad80e4a9e27d 100644 (file)
@@ -7,6 +7,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/linkage.h>
 #include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
@@ -792,6 +793,8 @@ void fixup_irqs(void)
                }
                spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
        }
+
+       tick_ops->disable_irq();
 }
 #endif
 
@@ -864,7 +867,7 @@ static void kill_prom_timer(void)
        : "g1", "g2");
 }
 
-void init_irqwork_curcpu(void)
+void notrace init_irqwork_curcpu(void)
 {
        int cpu = hard_smp_processor_id();
 
@@ -895,7 +898,7 @@ static void __cpuinit register_one_mondo(unsigned long paddr, unsigned long type
        }
 }
 
-void __cpuinit sun4v_register_mondo_queues(int this_cpu)
+void __cpuinit notrace sun4v_register_mondo_queues(int this_cpu)
 {
        struct trap_per_cpu *tb = &trap_block[this_cpu];
 
index f845f150f565b26a019dea86afa7a6b9d2970ce7..100ebd527499991f39b094709fe597fa77f571f6 100644 (file)
@@ -169,7 +169,7 @@ static unsigned long of_bus_default_get_flags(const u32 *addr, unsigned long fla
 
 static int of_bus_pci_match(struct device_node *np)
 {
-       if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+       if (!strcmp(np->name, "pci")) {
                const char *model = of_get_property(np, "model", NULL);
 
                if (model && !strcmp(model, "SUNW,simba"))
@@ -200,7 +200,7 @@ static int of_bus_simba_match(struct device_node *np)
        /* Treat PCI busses lacking ranges property just like
         * simba.
         */
-       if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) {
+       if (!strcmp(np->name, "pci")) {
                if (!of_find_property(np, "ranges", NULL))
                        return 1;
        }
@@ -429,7 +429,7 @@ static int __init use_1to1_mapping(struct device_node *pp)
         * it lacks a ranges property, and this will include
         * cases like Simba.
         */
-       if (!strcmp(pp->type, "pci") || !strcmp(pp->type, "pciex"))
+       if (!strcmp(pp->name, "pci"))
                return 0;
 
        return 1;
@@ -714,8 +714,7 @@ static unsigned int __init build_one_device_irq(struct of_device *op,
                                break;
                        }
                } else {
-                       if (!strcmp(pp->type, "pci") ||
-                           !strcmp(pp->type, "pciex")) {
+                       if (!strcmp(pp->name, "pci")) {
                                unsigned int this_orig_irq = irq;
 
                                irq = pci_irq_swizzle(dp, pp, irq);
index 55096195458fa0d358364075c5c7f06617112a55..80dad76f8b81c24b55cc3d26177cae9b7fa7ca79 100644 (file)
@@ -425,7 +425,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        dev->current_state = 4;         /* unknown power state */
        dev->error_state = pci_channel_io_normal;
 
-       if (!strcmp(type, "pci") || !strcmp(type, "pciex")) {
+       if (!strcmp(node->name, "pci")) {
                /* a PCI-PCI bridge */
                dev->hdr_type = PCI_HEADER_TYPE_BRIDGE;
                dev->rom_base_reg = PCI_ROM_ADDRESS1;
index ef5fe29202c2ff586f411dc35fa4095f927fd65b..f85b6bebb0be1c7548366e982270ed4e85c3a320 100644 (file)
@@ -575,7 +575,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
 {
        unsigned long csr_reg, csr, csr_error_bits;
        irqreturn_t ret = IRQ_NONE;
-       u16 stat;
+       u16 stat, *addr;
 
        if (is_pbm_a) {
                csr_reg = pbm->controller_regs + PSYCHO_PCIA_CTRL;
@@ -597,7 +597,9 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
                        printk("%s: PCI SERR signal asserted.\n", pbm->name);
                ret = IRQ_HANDLED;
        }
-       pci_read_config_word(pbm->pci_bus->self, PCI_STATUS, &stat);
+       addr = psycho_pci_config_mkaddr(pbm, pbm->pci_first_busno,
+                                       0, PCI_STATUS);
+       pci_config_read16(addr, &stat);
        if (stat & (PCI_STATUS_PARITY |
                    PCI_STATUS_SIG_TARGET_ABORT |
                    PCI_STATUS_REC_TARGET_ABORT |
@@ -605,7 +607,7 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm, int is_pbm
                    PCI_STATUS_SIG_SYSTEM_ERROR)) {
                printk("%s: PCI bus error, PCI_STATUS[%04x]\n",
                       pbm->name, stat);
-               pci_write_config_word(pbm->pci_bus->self, PCI_STATUS, 0xffff);
+               pci_config_write16(addr, 0xffff);
                ret = IRQ_HANDLED;
        }
        return ret;
@@ -744,16 +746,16 @@ static void psycho_register_error_handlers(struct pci_pbm_info *pbm)
         * the second will just error out since we do not pass in
         * IRQF_SHARED.
         */
-       err = request_irq(op->irqs[1], psycho_ue_intr, 0,
+       err = request_irq(op->irqs[1], psycho_ue_intr, IRQF_SHARED,
                          "PSYCHO_UE", pbm);
-       err = request_irq(op->irqs[2], psycho_ce_intr, 0,
+       err = request_irq(op->irqs[2], psycho_ce_intr, IRQF_SHARED,
                          "PSYCHO_CE", pbm);
 
        /* This one, however, ought not to fail.  We can just warn
         * about it since the system can still operate properly even
         * if this fails.
         */
-       err = request_irq(op->irqs[0], psycho_pcierr_intr, 0,
+       err = request_irq(op->irqs[0], psycho_pcierr_intr, IRQF_SHARED,
                          "PSYCHO_PCIERR", pbm);
        if (err)
                printk(KERN_WARNING "%s: Could not register PCIERR, "
index 3c048ac4e63859394ea7f28c4a75c91daec9df40..7151513f156e89ce428c0897e29ee7f4acfbde70 100644 (file)
@@ -156,55 +156,11 @@ static unsigned long psycho_pcislot_imap_offset(unsigned long ino)
                return PSYCHO_IMAP_B_SLOT0 + (slot * 8);
 }
 
-#define PSYCHO_IMAP_SCSI       0x1000UL
-#define PSYCHO_IMAP_ETH                0x1008UL
-#define PSYCHO_IMAP_BPP                0x1010UL
-#define PSYCHO_IMAP_AU_REC     0x1018UL
-#define PSYCHO_IMAP_AU_PLAY    0x1020UL
-#define PSYCHO_IMAP_PFAIL      0x1028UL
-#define PSYCHO_IMAP_KMS                0x1030UL
-#define PSYCHO_IMAP_FLPY       0x1038UL
-#define PSYCHO_IMAP_SHW                0x1040UL
-#define PSYCHO_IMAP_KBD                0x1048UL
-#define PSYCHO_IMAP_MS         0x1050UL
-#define PSYCHO_IMAP_SER                0x1058UL
-#define PSYCHO_IMAP_TIM0       0x1060UL
-#define PSYCHO_IMAP_TIM1       0x1068UL
-#define PSYCHO_IMAP_UE         0x1070UL
-#define PSYCHO_IMAP_CE         0x1078UL
-#define PSYCHO_IMAP_A_ERR      0x1080UL
-#define PSYCHO_IMAP_B_ERR      0x1088UL
-#define PSYCHO_IMAP_PMGMT      0x1090UL
-#define PSYCHO_IMAP_GFX                0x1098UL
-#define PSYCHO_IMAP_EUPA       0x10a0UL
-
-static unsigned long __psycho_onboard_imap_off[] = {
-/*0x20*/       PSYCHO_IMAP_SCSI,
-/*0x21*/       PSYCHO_IMAP_ETH,
-/*0x22*/       PSYCHO_IMAP_BPP,
-/*0x23*/       PSYCHO_IMAP_AU_REC,
-/*0x24*/       PSYCHO_IMAP_AU_PLAY,
-/*0x25*/       PSYCHO_IMAP_PFAIL,
-/*0x26*/       PSYCHO_IMAP_KMS,
-/*0x27*/       PSYCHO_IMAP_FLPY,
-/*0x28*/       PSYCHO_IMAP_SHW,
-/*0x29*/       PSYCHO_IMAP_KBD,
-/*0x2a*/       PSYCHO_IMAP_MS,
-/*0x2b*/       PSYCHO_IMAP_SER,
-/*0x2c*/       PSYCHO_IMAP_TIM0,
-/*0x2d*/       PSYCHO_IMAP_TIM1,
-/*0x2e*/       PSYCHO_IMAP_UE,
-/*0x2f*/       PSYCHO_IMAP_CE,
-/*0x30*/       PSYCHO_IMAP_A_ERR,
-/*0x31*/       PSYCHO_IMAP_B_ERR,
-/*0x32*/       PSYCHO_IMAP_PMGMT,
-/*0x33*/       PSYCHO_IMAP_GFX,
-/*0x34*/       PSYCHO_IMAP_EUPA,
-};
+#define PSYCHO_OBIO_IMAP_BASE  0x1000UL
+
 #define PSYCHO_ONBOARD_IRQ_BASE                0x20
-#define PSYCHO_ONBOARD_IRQ_LAST                0x34
 #define psycho_onboard_imap_offset(__ino) \
-       __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE]
+       (PSYCHO_OBIO_IMAP_BASE + (((__ino) & 0x1f) << 3))
 
 #define PSYCHO_ICLR_A_SLOT0    0x1400UL
 #define PSYCHO_ICLR_SCSI       0x1800UL
@@ -228,10 +184,6 @@ static unsigned int psycho_irq_build(struct device_node *dp,
                imap_off = psycho_pcislot_imap_offset(ino);
        } else {
                /* Onboard device */
-               if (ino > PSYCHO_ONBOARD_IRQ_LAST) {
-                       prom_printf("psycho_irq_build: Wacky INO [%x]\n", ino);
-                       prom_halt();
-               }
                imap_off = psycho_onboard_imap_offset(ino);
        }
 
@@ -318,23 +270,6 @@ static void sabre_wsync_handler(unsigned int ino, void *_arg1, void *_arg2)
 
 #define SABRE_IMAP_A_SLOT0     0x0c00UL
 #define SABRE_IMAP_B_SLOT0     0x0c20UL
-#define SABRE_IMAP_SCSI                0x1000UL
-#define SABRE_IMAP_ETH         0x1008UL
-#define SABRE_IMAP_BPP         0x1010UL
-#define SABRE_IMAP_AU_REC      0x1018UL
-#define SABRE_IMAP_AU_PLAY     0x1020UL
-#define SABRE_IMAP_PFAIL       0x1028UL
-#define SABRE_IMAP_KMS         0x1030UL
-#define SABRE_IMAP_FLPY                0x1038UL
-#define SABRE_IMAP_SHW         0x1040UL
-#define SABRE_IMAP_KBD         0x1048UL
-#define SABRE_IMAP_MS          0x1050UL
-#define SABRE_IMAP_SER         0x1058UL
-#define SABRE_IMAP_UE          0x1070UL
-#define SABRE_IMAP_CE          0x1078UL
-#define SABRE_IMAP_PCIERR      0x1080UL
-#define SABRE_IMAP_GFX         0x1098UL
-#define SABRE_IMAP_EUPA                0x10a0UL
 #define SABRE_ICLR_A_SLOT0     0x1400UL
 #define SABRE_ICLR_B_SLOT0     0x1480UL
 #define SABRE_ICLR_SCSI                0x1800UL
@@ -364,33 +299,10 @@ static unsigned long sabre_pcislot_imap_offset(unsigned long ino)
                return SABRE_IMAP_B_SLOT0 + (slot * 8);
 }
 
-static unsigned long __sabre_onboard_imap_off[] = {
-/*0x20*/       SABRE_IMAP_SCSI,
-/*0x21*/       SABRE_IMAP_ETH,
-/*0x22*/       SABRE_IMAP_BPP,
-/*0x23*/       SABRE_IMAP_AU_REC,
-/*0x24*/       SABRE_IMAP_AU_PLAY,
-/*0x25*/       SABRE_IMAP_PFAIL,
-/*0x26*/       SABRE_IMAP_KMS,
-/*0x27*/       SABRE_IMAP_FLPY,
-/*0x28*/       SABRE_IMAP_SHW,
-/*0x29*/       SABRE_IMAP_KBD,
-/*0x2a*/       SABRE_IMAP_MS,
-/*0x2b*/       SABRE_IMAP_SER,
-/*0x2c*/       0 /* reserved */,
-/*0x2d*/       0 /* reserved */,
-/*0x2e*/       SABRE_IMAP_UE,
-/*0x2f*/       SABRE_IMAP_CE,
-/*0x30*/       SABRE_IMAP_PCIERR,
-/*0x31*/       0 /* reserved */,
-/*0x32*/       0 /* reserved */,
-/*0x33*/       SABRE_IMAP_GFX,
-/*0x34*/       SABRE_IMAP_EUPA,
-};
-#define SABRE_ONBOARD_IRQ_BASE         0x20
-#define SABRE_ONBOARD_IRQ_LAST         0x30
+#define SABRE_OBIO_IMAP_BASE   0x1000UL
+#define SABRE_ONBOARD_IRQ_BASE 0x20
 #define sabre_onboard_imap_offset(__ino) \
-       __sabre_onboard_imap_off[(__ino) - SABRE_ONBOARD_IRQ_BASE]
+       (SABRE_OBIO_IMAP_BASE + (((__ino) & 0x1f) << 3))
 
 #define sabre_iclr_offset(ino)                                       \
        ((ino & 0x20) ? (SABRE_ICLR_SCSI + (((ino) & 0x1f) << 3)) :  \
@@ -453,10 +365,6 @@ static unsigned int sabre_irq_build(struct device_node *dp,
                imap_off = sabre_pcislot_imap_offset(ino);
        } else {
                /* onboard device */
-               if (ino > SABRE_ONBOARD_IRQ_LAST) {
-                       prom_printf("sabre_irq_build: Wacky INO [%x]\n", ino);
-                       prom_halt();
-               }
                imap_off = sabre_onboard_imap_offset(ino);
        }
 
index bd578cc4856d6de60ed4e3ba54cec2874b32480c..10306e476e388370812cb5f1f03c32d9c61879ef 100644 (file)
@@ -443,7 +443,7 @@ static const struct user_regset sparc64_regsets[] = {
         */
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
-               .n = 36 * sizeof(u64),
+               .n = 36,
                .size = sizeof(u64), .align = sizeof(u64),
                .get = genregs64_get, .set = genregs64_set
        },
@@ -455,7 +455,7 @@ static const struct user_regset sparc64_regsets[] = {
         */
        [REGSET_FP] = {
                .core_note_type = NT_PRFPREG,
-               .n = 35 * sizeof(u64),
+               .n = 35,
                .size = sizeof(u64), .align = sizeof(u64),
                .get = fpregs64_get, .set = fpregs64_set
        },
@@ -801,7 +801,7 @@ static const struct user_regset sparc32_regsets[] = {
         */
        [REGSET_GENERAL] = {
                .core_note_type = NT_PRSTATUS,
-               .n = 38 * sizeof(u32),
+               .n = 38,
                .size = sizeof(u32), .align = sizeof(u32),
                .get = genregs32_get, .set = genregs32_set
        },
@@ -817,7 +817,7 @@ static const struct user_regset sparc32_regsets[] = {
         */
        [REGSET_FP] = {
                .core_note_type = NT_PRFPREG,
-               .n = 99 * sizeof(u32),
+               .n = 99,
                .size = sizeof(u32), .align = sizeof(u32),
                .get = fpregs32_get, .set = fpregs32_set
        },
index 3d924121c7960dd5b577c291a9a2dd716a272b2d..c824df13f589a31bdd048ddc1464f8d7e1c9e6d9 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/linkage.h>
 #include <linux/kernel.h>
 #include <linux/signal.h>
 #include <linux/smp.h>
@@ -2453,7 +2454,7 @@ struct trap_per_cpu trap_block[NR_CPUS];
 /* This can get invoked before sched_init() so play it super safe
  * and use hard_smp_processor_id().
  */
-void init_cur_cpu_trap(struct thread_info *t)
+void notrace init_cur_cpu_trap(struct thread_info *t)
 {
        int cpu = hard_smp_processor_id();
        struct trap_per_cpu *p = &trap_block[cpu];
index 2c518fbc52ece13221e587ee71f11c81a4d5cec7..b225219c448ca4cc44c7de2402b8c894e8b5da3e 100644 (file)
@@ -382,14 +382,17 @@ config X86_OOSTORE
 # P6_NOPs are a relatively minor optimization that require a family >=
 # 6 processor, except that it is broken on certain VIA chips.
 # Furthermore, AMD chips prefer a totally different sequence of NOPs
-# (which work on all CPUs).  As a result, disallow these if we're
-# compiling X86_GENERIC but not X86_64 (these NOPs do work on all
-# x86-64 capable chips); the list of processors in the right-hand clause
-# are the cores that benefit from this optimization.
+# (which work on all CPUs).  In addition, it looks like Virtual PC
+# does not understand them.
+#
+# As a result, disallow these if we're not compiling for X86_64 (these
+# NOPs do work on all x86-64 capable chips); the list of processors in
+# the right-hand clause are the cores that benefit from this optimization.
 #
 config X86_P6_NOP
        def_bool y
-       depends on (X86_64 || !X86_GENERIC) && (M686 || MPENTIUMII || MPENTIUMIII || MPENTIUMM || MCORE2 || MPENTIUM4 || MPSC)
+       depends on X86_64
+       depends on (MCORE2 || MPENTIUM4 || MPSC)
 
 config X86_TSC
        def_bool y
index 69b4d060b21c4c32e8e40b45c9dc2171c1b56505..042fdc27bc925cd5719c73b443a39b5a3c1456d9 100644 (file)
@@ -101,10 +101,10 @@ static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
  */
 static int iommu_completion_wait(struct amd_iommu *iommu)
 {
-       int ret, ready = 0;
+       int ret = 0, ready = 0;
        unsigned status = 0;
        struct iommu_cmd cmd;
-       unsigned long i = 0;
+       unsigned long flags, i = 0;
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;
@@ -112,10 +112,12 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
 
        iommu->need_sync = 0;
 
-       ret = iommu_queue_command(iommu, &cmd);
+       spin_lock_irqsave(&iommu->lock, flags);
+
+       ret = __iommu_queue_command(iommu, &cmd);
 
        if (ret)
-               return ret;
+               goto out;
 
        while (!ready && (i < EXIT_LOOP_COUNT)) {
                ++i;
@@ -130,6 +132,8 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
 
        if (unlikely((i == EXIT_LOOP_COUNT) && printk_ratelimit()))
                printk(KERN_WARNING "AMD IOMMU: Completion wait loop failed\n");
+out:
+       spin_unlock_irqrestore(&iommu->lock, flags);
 
        return 0;
 }
@@ -140,6 +144,7 @@ static int iommu_completion_wait(struct amd_iommu *iommu)
 static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
 {
        struct iommu_cmd cmd;
+       int ret;
 
        BUG_ON(iommu == NULL);
 
@@ -147,9 +152,11 @@ static int iommu_queue_inv_dev_entry(struct amd_iommu *iommu, u16 devid)
        CMD_SET_TYPE(&cmd, CMD_INV_DEV_ENTRY);
        cmd.data[0] = devid;
 
+       ret = iommu_queue_command(iommu, &cmd);
+
        iommu->need_sync = 1;
 
-       return iommu_queue_command(iommu, &cmd);
+       return ret;
 }
 
 /*
@@ -159,6 +166,7 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
                u64 address, u16 domid, int pde, int s)
 {
        struct iommu_cmd cmd;
+       int ret;
 
        memset(&cmd, 0, sizeof(cmd));
        address &= PAGE_MASK;
@@ -171,9 +179,11 @@ static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
        if (pde) /* PDE bit - we wan't flush everything not only the PTEs */
                cmd.data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
 
+       ret = iommu_queue_command(iommu, &cmd);
+
        iommu->need_sync = 1;
 
-       return iommu_queue_command(iommu, &cmd);
+       return ret;
 }
 
 /*
index 9ee24e6bc4b0e5a661c4ac3dd669c60bf1f82a45..732d1f4e10ee641020f9af9b1851be4e9bbad99e 100644 (file)
 #include <asm/uaccess.h>
 #include <asm/desc.h>
 #include <asm/i8253.h>
+#include <asm/olpc.h>
 #include <asm/paravirt.h>
 #include <asm/reboot.h>
 
@@ -2217,7 +2218,7 @@ static int __init apm_init(void)
 
        dmi_check_system(apm_dmi_table);
 
-       if (apm_info.bios.version == 0 || paravirt_enabled()) {
+       if (apm_info.bios.version == 0 || paravirt_enabled() || machine_is_olpc()) {
                printk(KERN_INFO "apm: BIOS not found.\n");
                return -ENODEV;
        }
index 8aab8517642e7ba34c3c91da7403c4892b01b53d..4e456bd955bb8389c4c7536d23635fdc97ec67f5 100644 (file)
@@ -344,31 +344,15 @@ static void __init early_cpu_detect(void)
 
 /*
  * The NOPL instruction is supposed to exist on all CPUs with
- * family >= 6, unfortunately, that's not true in practice because
+ * family >= 6; unfortunately, that's not true in practice because
  * of early VIA chips and (more importantly) broken virtualizers that
- * are not easy to detect.  Hence, probe for it based on first
- * principles.
+ * are not easy to detect.  In the latter case it doesn't even *fail*
+ * reliably, so probing for it doesn't even work.  Disable it completely
+ * unless we can find a reliable way to detect all the broken cases.
  */
 static void __cpuinit detect_nopl(struct cpuinfo_x86 *c)
 {
-       const u32 nopl_signature = 0x888c53b1; /* Random number */
-       u32 has_nopl = nopl_signature;
-
        clear_cpu_cap(c, X86_FEATURE_NOPL);
-       if (c->x86 >= 6) {
-               asm volatile("\n"
-                            "1:      .byte 0x0f,0x1f,0xc0\n" /* nopl %eax */
-                            "2:\n"
-                            "        .section .fixup,\"ax\"\n"
-                            "3:      xor %0,%0\n"
-                            "        jmp 2b\n"
-                            "        .previous\n"
-                            _ASM_EXTABLE(1b,3b)
-                            : "+a" (has_nopl));
-
-               if (has_nopl == nopl_signature)
-                       set_cpu_cap(c, X86_FEATURE_NOPL);
-       }
 }
 
 static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
index 9af89078f7bb0cb2b6ce7ed958c9483b24d4402e..66e48aa2dd1b4dae8739f69841337386cc670889 100644 (file)
@@ -1203,7 +1203,7 @@ static int __init parse_memmap_opt(char *p)
        if (!p)
                return -EINVAL;
 
-       if (!strcmp(p, "exactmap")) {
+       if (!strncmp(p, "exactmap", 8)) {
 #ifdef CONFIG_CRASH_DUMP
                /*
                 * If we are doing a crash dump, we still need to know
index f2d43bc7551488a61390c27cd429a9721fefbc26..ff7d3b0124f1db07bbb0750ec0fe0e9237f66574 100644 (file)
@@ -139,6 +139,7 @@ static int __init create_setup_data_nodes(struct dentry *parent)
                if (PageHighMem(pg)) {
                        data = ioremap_cache(pa_data, sizeof(*data));
                        if (!data) {
+                               kfree(node);
                                error = -ENXIO;
                                goto err_dir;
                        }
index f47f0eb886b8ddeab27ec8a8fd319801c45ef503..8282a213968191368c3b3a4fdaf167ae20afa900 100644 (file)
@@ -69,6 +69,9 @@ static int gdb_x86vector = -1;
  */
 void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
+#ifndef CONFIG_X86_32
+       u32 *gdb_regs32 = (u32 *)gdb_regs;
+#endif
        gdb_regs[GDB_AX]        = regs->ax;
        gdb_regs[GDB_BX]        = regs->bx;
        gdb_regs[GDB_CX]        = regs->cx;
@@ -76,9 +79,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
        gdb_regs[GDB_SI]        = regs->si;
        gdb_regs[GDB_DI]        = regs->di;
        gdb_regs[GDB_BP]        = regs->bp;
-       gdb_regs[GDB_PS]        = regs->flags;
        gdb_regs[GDB_PC]        = regs->ip;
 #ifdef CONFIG_X86_32
+       gdb_regs[GDB_PS]        = regs->flags;
        gdb_regs[GDB_DS]        = regs->ds;
        gdb_regs[GDB_ES]        = regs->es;
        gdb_regs[GDB_CS]        = regs->cs;
@@ -94,6 +97,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
        gdb_regs[GDB_R13]       = regs->r13;
        gdb_regs[GDB_R14]       = regs->r14;
        gdb_regs[GDB_R15]       = regs->r15;
+       gdb_regs32[GDB_PS]      = regs->flags;
+       gdb_regs32[GDB_CS]      = regs->cs;
+       gdb_regs32[GDB_SS]      = regs->ss;
 #endif
        gdb_regs[GDB_SP]        = regs->sp;
 }
@@ -112,6 +118,9 @@ void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs)
  */
 void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
 {
+#ifndef CONFIG_X86_32
+       u32 *gdb_regs32 = (u32 *)gdb_regs;
+#endif
        gdb_regs[GDB_AX]        = 0;
        gdb_regs[GDB_BX]        = 0;
        gdb_regs[GDB_CX]        = 0;
@@ -129,8 +138,10 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
        gdb_regs[GDB_FS]        = 0xFFFF;
        gdb_regs[GDB_GS]        = 0xFFFF;
 #else
-       gdb_regs[GDB_PS]        = *(unsigned long *)(p->thread.sp + 8);
-       gdb_regs[GDB_PC]        = 0;
+       gdb_regs32[GDB_PS]      = *(unsigned long *)(p->thread.sp + 8);
+       gdb_regs32[GDB_CS]      = __KERNEL_CS;
+       gdb_regs32[GDB_SS]      = __KERNEL_DS;
+       gdb_regs[GDB_PC]        = p->thread.ip;
        gdb_regs[GDB_R8]        = 0;
        gdb_regs[GDB_R9]        = 0;
        gdb_regs[GDB_R10]       = 0;
@@ -153,6 +164,9 @@ void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p)
  */
 void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
 {
+#ifndef CONFIG_X86_32
+       u32 *gdb_regs32 = (u32 *)gdb_regs;
+#endif
        regs->ax                = gdb_regs[GDB_AX];
        regs->bx                = gdb_regs[GDB_BX];
        regs->cx                = gdb_regs[GDB_CX];
@@ -160,9 +174,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
        regs->si                = gdb_regs[GDB_SI];
        regs->di                = gdb_regs[GDB_DI];
        regs->bp                = gdb_regs[GDB_BP];
-       regs->flags             = gdb_regs[GDB_PS];
        regs->ip                = gdb_regs[GDB_PC];
 #ifdef CONFIG_X86_32
+       regs->flags             = gdb_regs[GDB_PS];
        regs->ds                = gdb_regs[GDB_DS];
        regs->es                = gdb_regs[GDB_ES];
        regs->cs                = gdb_regs[GDB_CS];
@@ -175,6 +189,9 @@ void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs)
        regs->r13               = gdb_regs[GDB_R13];
        regs->r14               = gdb_regs[GDB_R14];
        regs->r15               = gdb_regs[GDB_R15];
+       regs->flags             = gdb_regs32[GDB_PS];
+       regs->cs                = gdb_regs32[GDB_CS];
+       regs->ss                = gdb_regs32[GDB_SS];
 #endif
 }
 
@@ -378,10 +395,8 @@ int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
                if (remcomInBuffer[0] == 's') {
                        linux_regs->flags |= X86_EFLAGS_TF;
                        kgdb_single_step = 1;
-                       if (kgdb_contthread) {
-                               atomic_set(&kgdb_cpu_doing_single_step,
-                                          raw_smp_processor_id());
-                       }
+                       atomic_set(&kgdb_cpu_doing_single_step,
+                                  raw_smp_processor_id());
                }
 
                get_debugreg(dr6, 6);
@@ -466,9 +481,15 @@ static int __kgdb_notify(struct die_args *args, unsigned long cmd)
 
        case DIE_DEBUG:
                if (atomic_read(&kgdb_cpu_doing_single_step) ==
-                       raw_smp_processor_id() &&
-                       user_mode(regs))
-                       return single_step_cont(regs, args);
+                   raw_smp_processor_id()) {
+                       if (user_mode(regs))
+                               return single_step_cont(regs, args);
+                       break;
+               } else if (test_thread_flag(TIF_SINGLESTEP))
+                       /* This means a user thread is single stepping
+                        * a system call which should be ignored
+                        */
+                       return NOTIFY_DONE;
                /* fall through */
        default:
                if (user_mode(regs))
index 7fc4d5b0a6a0f99a4d1d9c4df685a5a4d3a135bb..876e91890777ae9758e5efcb7dc72075a26e341e 100644 (file)
@@ -246,6 +246,14 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
        return 1;
 }
 
+static cpumask_t c1e_mask = CPU_MASK_NONE;
+static int c1e_detected;
+
+void c1e_remove_cpu(int cpu)
+{
+       cpu_clear(cpu, c1e_mask);
+}
+
 /*
  * C1E aware idle routine. We check for C1E active in the interrupt
  * pending message MSR. If we detect C1E, then we handle it the same
@@ -253,9 +261,6 @@ static int __cpuinit check_c1e_idle(const struct cpuinfo_x86 *c)
  */
 static void c1e_idle(void)
 {
-       static cpumask_t c1e_mask = CPU_MASK_NONE;
-       static int c1e_detected;
-
        if (need_resched())
                return;
 
@@ -265,8 +270,10 @@ static void c1e_idle(void)
                rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
                if (lo & K8_INTP_C1E_ACTIVE_MASK) {
                        c1e_detected = 1;
-                       mark_tsc_unstable("TSC halt in C1E");
-                       printk(KERN_INFO "System has C1E enabled\n");
+                       if (!boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
+                               mark_tsc_unstable("TSC halt in AMD C1E");
+                       printk(KERN_INFO "System has AMD C1E enabled\n");
+                       set_cpu_cap(&boot_cpu_data, X86_FEATURE_AMDC1E);
                }
        }
 
index 3b7a1ddcc0bce7eca8c989906fa377d4f0322f50..31f40b24bf5d72f4d62c204307a1bd826c726c32 100644 (file)
@@ -55,6 +55,7 @@
 #include <asm/tlbflush.h>
 #include <asm/cpu.h>
 #include <asm/kdebug.h>
+#include <asm/idle.h>
 
 asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
 
@@ -88,6 +89,7 @@ static void cpu_exit_clear(void)
        cpu_clear(cpu, cpu_callin_map);
 
        numa_remove_cpu(cpu);
+       c1e_remove_cpu(cpu);
 }
 
 /* We don't actually take CPU down, just spin without interrupts. */
index 71553b664e2af8601361a9af3413599b752a3e5c..e12e0e4dd2566c2959623d4475053c5fcbcd65d3 100644 (file)
@@ -93,6 +93,8 @@ DECLARE_PER_CPU(int, cpu_state);
 static inline void play_dead(void)
 {
        idle_task_exit();
+       c1e_remove_cpu(raw_smp_processor_id());
+
        mb();
        /* Ack it */
        __get_cpu_var(cpu_state) = CPU_DEAD;
index 362d4e7f2d389b81e345fa27b13db78e80c5980a..9838f2539dfc4cb93697a98a98752012b885a2d7 100644 (file)
@@ -670,6 +670,10 @@ void __init setup_arch(char **cmdline_p)
 
        parse_early_param();
 
+#ifdef CONFIG_X86_64
+       check_efer();
+#endif
+
 #if defined(CONFIG_VMI) && defined(CONFIG_X86_32)
        /*
         * Must be before kernel pagetables are setup
@@ -738,7 +742,6 @@ void __init setup_arch(char **cmdline_p)
 #else
        num_physpages = max_pfn;
 
-       check_efer();
 
        /* How many end-of-memory variables you have, grandma! */
        /* need this before calling reserve_initrd */
index 0c029e8959c7f7221d4687b8465812393e1faff0..7766d36983fcd7440f82435bcfbbcd37c1d80a6b 100644 (file)
@@ -61,7 +61,7 @@ static void vsmp_irq_enable(void)
        native_restore_fl((flags | X86_EFLAGS_IF) & (~X86_EFLAGS_AC));
 }
 
-static unsigned __init vsmp_patch(u8 type, u16 clobbers, void *ibuf,
+static unsigned __init_or_module vsmp_patch(u8 type, u16 clobbers, void *ibuf,
                                  unsigned long addr, unsigned len)
 {
        switch (type) {
index 0bfe2bd305eb286aee2890e2be95b397c462d74c..3da2508eb22a2d9577a0a24847065af3e21acbcc 100644 (file)
@@ -711,6 +711,10 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp)
        u64 *spte;
        int young = 0;
 
+       /* always return old for EPT */
+       if (!shadow_accessed_mask)
+               return 0;
+
        spte = rmap_next(kvm, rmapp, NULL);
        while (spte) {
                int _young;
index e2ee264740c7dbb6ea6717b3aa7617c393fd4831..8233b86c778cfd0a01b2ca96dbe7d27776381037 100644 (file)
@@ -62,6 +62,7 @@ static int npt = 1;
 module_param(npt, int, S_IRUGO);
 
 static void kvm_reput_irq(struct vcpu_svm *svm);
+static void svm_flush_tlb(struct kvm_vcpu *vcpu);
 
 static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu)
 {
@@ -878,6 +879,10 @@ set:
 static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
 {
        unsigned long host_cr4_mce = read_cr4() & X86_CR4_MCE;
+       unsigned long old_cr4 = to_svm(vcpu)->vmcb->save.cr4;
+
+       if (npt_enabled && ((old_cr4 ^ cr4) & X86_CR4_PGE))
+               force_new_asid(vcpu);
 
        vcpu->arch.cr4 = cr4;
        if (!npt_enabled)
@@ -1027,6 +1032,13 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
                KVMTRACE_3D(TDP_FAULT, &svm->vcpu, error_code,
                            (u32)fault_address, (u32)(fault_address >> 32),
                            handler);
+       /*
+        * FIXME: Tis shouldn't be necessary here, but there is a flush
+        * missing in the MMU code. Until we find this bug, flush the
+        * complete TLB here on an NPF
+        */
+       if (npt_enabled)
+               svm_flush_tlb(&svm->vcpu);
 
        if (event_injection)
                kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
index 2a69773e3b26235f3261aea232ef5fe17411d6cb..7041cc52b562eccc98f4a5fd060390709bc915b4 100644 (file)
@@ -3301,8 +3301,7 @@ static int __init vmx_init(void)
                kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
                        VMX_EPT_WRITABLE_MASK |
                        VMX_EPT_DEFAULT_MT << VMX_EPT_MT_EPTE_SHIFT);
-               kvm_mmu_set_mask_ptes(0ull, VMX_EPT_FAKE_ACCESSED_MASK,
-                               VMX_EPT_FAKE_DIRTY_MASK, 0ull,
+               kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
                                VMX_EPT_EXECUTABLE_MASK);
                kvm_enable_tdp();
        } else
index 425a13436b3f45a3b84c5805b85025f58ce4b665..23e8373507adec0d49cec6ab7637c17da2fc61b2 100644 (file)
@@ -370,8 +370,6 @@ enum vmcs_field {
 #define VMX_EPT_READABLE_MASK                  0x1ull
 #define VMX_EPT_WRITABLE_MASK                  0x2ull
 #define VMX_EPT_EXECUTABLE_MASK                        0x4ull
-#define VMX_EPT_FAKE_ACCESSED_MASK             (1ull << 62)
-#define VMX_EPT_FAKE_DIRTY_MASK                        (1ull << 63)
 
 #define VMX_EPT_IDENTITY_PAGETABLE_ADDR                0xfffbc000ul
 
index d37f29376b0ce455ae3907051a58779f4b995a25..60ec1d08ff24b6a03917e957d707b183b1b776e6 100644 (file)
@@ -458,11 +458,7 @@ static void __init pagetable_init(void)
 {
        pgd_t *pgd_base = swapper_pg_dir;
 
-       paravirt_pagetable_setup_start(pgd_base);
-
        permanent_kmaps_init(pgd_base);
-
-       paravirt_pagetable_setup_done(pgd_base);
 }
 
 #ifdef CONFIG_ACPI_SLEEP
index 0227694f7dab9b156350eaef0e90f79e8ec2ecc4..8a5f1614a3d57cde8d7495c1b71f8e8542e99c64 100644 (file)
@@ -295,10 +295,12 @@ static void nmi_cpu_shutdown(void *dummy)
 
 static void nmi_shutdown(void)
 {
-       struct op_msrs *msrs = &get_cpu_var(cpu_msrs);
+       struct op_msrs *msrs;
+
        nmi_enabled = 0;
        on_each_cpu(nmi_cpu_shutdown, NULL, 1);
        unregister_die_notifier(&profile_exceptions_nb);
+       msrs = &get_cpu_var(cpu_msrs);
        model->shutdown(msrs);
        free_msrs();
        put_cpu_var(cpu_msrs);
index b6acc3a0af46d0adeb44a99a8b8d78e1ef8c5140..d679010838883195da63cfa7a7bbef7cfa71fe03 100644 (file)
@@ -42,7 +42,7 @@ char * __init xen_memory_setup(void)
 
        e820.nr_map = 0;
 
-       e820_add_region(0, PFN_PHYS(max_pfn), E820_RAM);
+       e820_add_region(0, PFN_PHYS((u64)max_pfn), E820_RAM);
 
        /*
         * Even though this is normal, usable memory under Xen, reserve
index 228b6447e89f295346bcb2d07e295f467bc10f35..79c14996ac110ab1a2cd34af04049df5963a1019 100644 (file)
@@ -49,6 +49,7 @@ int blk_verify_command(struct blk_cmd_filter *filter,
 }
 EXPORT_SYMBOL(blk_verify_command);
 
+#if 0
 /* and now, the sysfs stuff */
 static ssize_t rcf_cmds_show(struct blk_cmd_filter *filter, char *page,
                             int rw)
@@ -233,3 +234,4 @@ void blk_unregister_filter(struct gendisk *disk)
        kobject_put(disk->holder_dir->parent);
 }
 EXPORT_SYMBOL(blk_unregister_filter);
+#endif
index b1d08a8f50030da3bb5d6a74726b5a72fdffe24b..e6b4606e36b68a51448d73b755aab75d91e0fa80 100644 (file)
@@ -1499,7 +1499,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
         * off.
         */
        if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2652) {
-               int rc = piix_disable_ahci(pdev);
+               rc = piix_disable_ahci(pdev);
                if (rc)
                        return rc;
        }
index 3ead02fe379e26ca1dac0130a323e06888ba7f35..5032c32fa505f2254439c3b4940aa85f841ff220 100644 (file)
@@ -96,6 +96,7 @@ enum {
        PORT_SCR                = 0x20,
 
        /* HOST_CTL bits */
+       HCTL_LEDEN              = (1 << 3),  /* enable LED operation */
        HCTL_IRQOFF             = (1 << 8),  /* global IRQ off */
        HCTL_FTHD0              = (1 << 10), /* fifo threshold 0 */
        HCTL_FTHD1              = (1 << 11), /* fifo threshold 1*/
@@ -540,7 +541,7 @@ static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
        void __iomem *port_base = inic_port_base(ap);
 
        /* fire up the ADMA engine */
-       writew(HCTL_FTHD0, port_base + HOST_CTL);
+       writew(HCTL_FTHD0 | HCTL_LEDEN, port_base + HOST_CTL);
        writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL);
        writeb(0, port_base + PORT_CPB_PTQFIFO);
 
index 1e1f3f3757ae7bf98fd7ce2d39cfafdc644095f0..14601dc05e4162eeab2f544fd02da2738cd17db4 100644 (file)
@@ -309,6 +309,8 @@ static void nv_nf2_freeze(struct ata_port *ap);
 static void nv_nf2_thaw(struct ata_port *ap);
 static void nv_ck804_freeze(struct ata_port *ap);
 static void nv_ck804_thaw(struct ata_port *ap);
+static int nv_hardreset(struct ata_link *link, unsigned int *class,
+                       unsigned long deadline);
 static int nv_adma_slave_config(struct scsi_device *sdev);
 static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
 static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
@@ -403,28 +405,45 @@ static struct scsi_host_template nv_swncq_sht = {
        .slave_configure        = nv_swncq_slave_config,
 };
 
-static struct ata_port_operations nv_generic_ops = {
+/* OSDL bz3352 reports that some nv controllers can't determine device
+ * signature reliably and nv_hardreset is implemented to work around
+ * the problem.  This was reported on nf3 and it's unclear whether any
+ * other controllers are affected.  However, the workaround has been
+ * applied to all variants and there isn't much to gain by trying to
+ * find out exactly which ones are affected at this point especially
+ * because NV has moved over to ahci for newer controllers.
+ */
+static struct ata_port_operations nv_common_ops = {
        .inherits               = &ata_bmdma_port_ops,
-       .hardreset              = ATA_OP_NULL,
+       .hardreset              = nv_hardreset,
        .scr_read               = nv_scr_read,
        .scr_write              = nv_scr_write,
 };
 
+/* OSDL bz11195 reports that link doesn't come online after hardreset
+ * on generic nv's and there have been several other similar reports
+ * on linux-ide.  Disable hardreset for generic nv's.
+ */
+static struct ata_port_operations nv_generic_ops = {
+       .inherits               = &nv_common_ops,
+       .hardreset              = ATA_OP_NULL,
+};
+
 static struct ata_port_operations nv_nf2_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
        .freeze                 = nv_nf2_freeze,
        .thaw                   = nv_nf2_thaw,
 };
 
 static struct ata_port_operations nv_ck804_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
        .freeze                 = nv_ck804_freeze,
        .thaw                   = nv_ck804_thaw,
        .host_stop              = nv_ck804_host_stop,
 };
 
 static struct ata_port_operations nv_adma_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
 
        .check_atapi_dma        = nv_adma_check_atapi_dma,
        .sff_tf_read            = nv_adma_tf_read,
@@ -448,7 +467,7 @@ static struct ata_port_operations nv_adma_ops = {
 };
 
 static struct ata_port_operations nv_swncq_ops = {
-       .inherits               = &nv_generic_ops,
+       .inherits               = &nv_common_ops,
 
        .qc_defer               = ata_std_qc_defer,
        .qc_prep                = nv_swncq_qc_prep,
@@ -1586,6 +1605,21 @@ static void nv_mcp55_thaw(struct ata_port *ap)
        ata_sff_thaw(ap);
 }
 
+static int nv_hardreset(struct ata_link *link, unsigned int *class,
+                       unsigned long deadline)
+{
+       int rc;
+
+       /* SATA hardreset fails to retrieve proper device signature on
+        * some controllers.  Request follow up SRST.  For more info,
+        * see http://bugzilla.kernel.org/show_bug.cgi?id=3352
+        */
+       rc = sata_sff_hardreset(link, class, deadline);
+       if (rc)
+               return rc;
+       return -EAGAIN;
+}
+
 static void nv_adma_error_handler(struct ata_port *ap)
 {
        struct nv_adma_port_priv *pp = ap->private_data;
index 41b2204ebc6e1341dbc4b12d256309e0a33c3f18..5503bfc8e1320e0a362b2f4ffd57e043104ca1d7 100644 (file)
@@ -1270,7 +1270,7 @@ static int comp_tx(struct eni_dev *eni_dev,int *pcr,int reserved,int *pre,
                        if (*pre < 3) (*pre)++; /* else fail later */
                        div = pre_div[*pre]*-*pcr;
                        DPRINTK("max div %d\n",div);
-                       *res = (TS_CLOCK+div-1)/div-1;
+                       *res = DIV_ROUND_UP(TS_CLOCK, div)-1;
                }
                if (*res < 0) *res = 0;
                if (*res > MID_SEG_MAX_RATE) *res = MID_SEG_MAX_RATE;
index c0ac728dc5645ba6b5f7d2a213d9903b0a88a1e7..615412364e9930aa042b682e503d3816f2498b8e 100644 (file)
@@ -635,7 +635,7 @@ static int make_rate (const hrz_dev * dev, u32 c, rounding r,
                // take care of rounding
                switch (r) {
                        case round_down:
-                               pre = (br+(c<<div)-1)/(c<<div);
+                               pre = DIV_ROUND_UP(br, c<<div);
                                // but p must be non-zero
                                if (!pre)
                                        pre = 1;
@@ -668,7 +668,7 @@ static int make_rate (const hrz_dev * dev, u32 c, rounding r,
                        // take care of rounding
                        switch (r) {
                                case round_down:
-                                       pre = (br+(c<<div)-1)/(c<<div);
+                                       pre = DIV_ROUND_UP(br, c<<div);
                                        break;
                                case round_nearest:
                                        pre = (br+(c<<div)/2)/(c<<div);
@@ -698,7 +698,7 @@ got_it:
                if (bits)
                        *bits = (div<<CLOCK_SELECT_SHIFT) | (pre-1);
                if (actual) {
-                       *actual = (br + (pre<<div) - 1) / (pre<<div);
+                       *actual = DIV_ROUND_UP(br, pre<<div);
                        PRINTD (DBG_QOS, "actual rate: %u", *actual);
                }
                return 0;
@@ -1967,7 +1967,7 @@ static int __devinit hrz_init (hrz_dev * dev) {
   // Set the max AAL5 cell count to be just enough to contain the
   // largest AAL5 frame that the user wants to receive
   wr_regw (dev, MAX_AAL5_CELL_COUNT_OFF,
-          (max_rx_size + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD);
+          DIV_ROUND_UP(max_rx_size + ATM_AAL5_TRAILER, ATM_CELL_PAYLOAD));
   
   // Enable receive
   wr_regw (dev, RX_CONFIG_OFF, rd_regw (dev, RX_CONFIG_OFF) | RX_ENABLE);
index 3a504e94a4d9439c5c017c5d32797218a03294fe..e33ae0025b1214c45e0380e495d7e135dc4a59a5 100644 (file)
@@ -1114,11 +1114,8 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
 
        rpp = &vc->rcv.rx_pool;
 
+       __skb_queue_tail(&rpp->queue, skb);
        rpp->len += skb->len;
-       if (!rpp->count++)
-               rpp->first = skb;
-       *rpp->last = skb;
-       rpp->last = &skb->next;
 
        if (stat & SAR_RSQE_EPDU) {
                unsigned char *l1l2;
@@ -1145,7 +1142,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
                        atomic_inc(&vcc->stats->rx_err);
                        return;
                }
-               if (rpp->count > 1) {
+               if (skb_queue_len(&rpp->queue) > 1) {
                        struct sk_buff *sb;
 
                        skb = dev_alloc_skb(rpp->len);
@@ -1161,12 +1158,9 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
                                dev_kfree_skb(skb);
                                return;
                        }
-                       sb = rpp->first;
-                       for (i = 0; i < rpp->count; i++) {
+                       skb_queue_walk(&rpp->queue, sb)
                                memcpy(skb_put(skb, sb->len),
                                       sb->data, sb->len);
-                               sb = sb->next;
-                       }
 
                        recycle_rx_pool_skb(card, rpp);
 
@@ -1180,7 +1174,6 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
                        return;
                }
 
-               skb->next = NULL;
                flush_rx_pool(card, rpp);
 
                if (!atm_charge(vcc, skb->truesize)) {
@@ -1918,25 +1911,18 @@ recycle_rx_skb(struct idt77252_dev *card, struct sk_buff *skb)
 static void
 flush_rx_pool(struct idt77252_dev *card, struct rx_pool *rpp)
 {
+       skb_queue_head_init(&rpp->queue);
        rpp->len = 0;
-       rpp->count = 0;
-       rpp->first = NULL;
-       rpp->last = &rpp->first;
 }
 
 static void
 recycle_rx_pool_skb(struct idt77252_dev *card, struct rx_pool *rpp)
 {
-       struct sk_buff *skb, *next;
-       int i;
+       struct sk_buff *skb, *tmp;
 
-       skb = rpp->first;
-       for (i = 0; i < rpp->count; i++) {
-               next = skb->next;
-               skb->next = NULL;
+       skb_queue_walk_safe(&rpp->queue, skb, tmp)
                recycle_rx_skb(card, skb);
-               skb = next;
-       }
+
        flush_rx_pool(card, rpp);
 }
 
@@ -2537,7 +2523,7 @@ idt77252_close(struct atm_vcc *vcc)
                waitfor_idle(card);
                spin_unlock_irqrestore(&card->cmd_lock, flags);
 
-               if (vc->rcv.rx_pool.count) {
+               if (skb_queue_len(&vc->rcv.rx_pool.queue) != 0) {
                        DPRINTK("%s: closing a VC with pending rx buffers.\n",
                                card->name);
 
@@ -2970,7 +2956,7 @@ close_card_oam(struct idt77252_dev *card)
                        waitfor_idle(card);
                        spin_unlock_irqrestore(&card->cmd_lock, flags);
 
-                       if (vc->rcv.rx_pool.count) {
+                       if (skb_queue_len(&vc->rcv.rx_pool.queue) != 0) {
                                DPRINTK("%s: closing a VC "
                                        "with pending rx buffers.\n",
                                        card->name);
index e83eaf120da0f23f83bcf138503fda436e844a4c..5042bb2dab15d0d13b91a08f7acea412a71a2d6b 100644 (file)
@@ -173,10 +173,8 @@ struct scq_info
 };
 
 struct rx_pool {
-       struct sk_buff          *first;
-       struct sk_buff          **last;
+       struct sk_buff_head     queue;
        unsigned int            len;
-       unsigned int            count;
 };
 
 struct aal1 {
index 58583c6ac5be556f1297ae0353e1f5b95dc56d17..752b1ba81f7e9bbd5ff56944723ae6740318dad5 100644 (file)
@@ -496,8 +496,8 @@ static int open_rx_first(struct atm_vcc *vcc)
                        vcc->qos.rxtp.max_sdu = 65464;
                        /* fix this - we may want to receive 64kB SDUs
                           later */
-               cells = (vcc->qos.rxtp.max_sdu+ATM_AAL5_TRAILER+
-                   ATM_CELL_PAYLOAD-1)/ATM_CELL_PAYLOAD;
+               cells = DIV_ROUND_UP(vcc->qos.rxtp.max_sdu + ATM_AAL5_TRAILER,
+                               ATM_CELL_PAYLOAD);
                zatm_vcc->pool = pool_index(cells*ATM_CELL_PAYLOAD);
        }
        else {
@@ -820,7 +820,7 @@ static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr)
                        }
                        else {
                                i = 255;
-                               m = (ATM_OC3_PCR*255+max-1)/max;
+                               m = DIV_ROUND_UP(ATM_OC3_PCR*255, max);
                        }
                }
                if (i > m) {
index 5b4c6e649c11170803a8ed7bedc7ca333c69a99a..93f3690396a5176de5cec3fb3151ef9e1670299d 100644 (file)
@@ -159,11 +159,8 @@ struct aoedev {
        sector_t ssize;
        struct timer_list timer;
        spinlock_t lock;
-       struct sk_buff *sendq_hd; /* packets needing to be sent, list head */
-       struct sk_buff *sendq_tl;
-       struct sk_buff *skbpool_hd;
-       struct sk_buff *skbpool_tl;
-       int nskbpool;
+       struct sk_buff_head sendq;
+       struct sk_buff_head skbpool;
        mempool_t *bufpool;     /* for deadlock-free Buf allocation */
        struct list_head bufq;  /* queue of bios to work on */
        struct buf *inprocess;  /* the one we're currently working on */
@@ -199,7 +196,7 @@ int aoedev_flush(const char __user *str, size_t size);
 
 int aoenet_init(void);
 void aoenet_exit(void);
-void aoenet_xmit(struct sk_buff *);
+void aoenet_xmit(struct sk_buff_head *);
 int is_aoe_netif(struct net_device *ifp);
 int set_aoe_iflist(const char __user *str, size_t size);
 
index 0c39782b26600f5d89d83e3f38c964aac9a28fbd..fd2cf5439a1c274a097118952f4f25dc9f101fd4 100644 (file)
@@ -158,9 +158,9 @@ aoeblk_release(struct inode *inode, struct file *filp)
 static int
 aoeblk_make_request(struct request_queue *q, struct bio *bio)
 {
+       struct sk_buff_head queue;
        struct aoedev *d;
        struct buf *buf;
-       struct sk_buff *sl;
        ulong flags;
 
        blk_queue_bounce(q, &bio);
@@ -213,11 +213,11 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio)
        list_add_tail(&buf->bufs, &d->bufq);
 
        aoecmd_work(d);
-       sl = d->sendq_hd;
-       d->sendq_hd = d->sendq_tl = NULL;
+       __skb_queue_head_init(&queue);
+       skb_queue_splice_init(&d->sendq, &queue);
 
        spin_unlock_irqrestore(&d->lock, flags);
-       aoenet_xmit(sl);
+       aoenet_xmit(&queue);
 
        return 0;
 }
index 181ebb85f0be582e95206aa144c04ee26ff016bc..1f56d2c5b7fc67acb83899494c9376297a030f6c 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/smp_lock.h>
+#include <linux/skbuff.h>
 #include "aoe.h"
 
 enum {
@@ -103,7 +104,12 @@ loop:
                spin_lock_irqsave(&d->lock, flags);
                goto loop;
        }
-       aoenet_xmit(skb);
+       if (skb) {
+               struct sk_buff_head queue;
+               __skb_queue_head_init(&queue);
+               __skb_queue_tail(&queue, skb);
+               aoenet_xmit(&queue);
+       }
        aoecmd_cfg(major, minor);
        return 0;
 }
index 2f1746295d06fc438ac4b1ba923c2aeb1d634dd8..e33da30be4c4cc62a88f99e5b9799614e9e731ec 100644 (file)
@@ -114,29 +114,22 @@ ifrotate(struct aoetgt *t)
 static void
 skb_pool_put(struct aoedev *d, struct sk_buff *skb)
 {
-       if (!d->skbpool_hd)
-               d->skbpool_hd = skb;
-       else
-               d->skbpool_tl->next = skb;
-       d->skbpool_tl = skb;
+       __skb_queue_tail(&d->skbpool, skb);
 }
 
 static struct sk_buff *
 skb_pool_get(struct aoedev *d)
 {
-       struct sk_buff *skb;
+       struct sk_buff *skb = skb_peek(&d->skbpool);
 
-       skb = d->skbpool_hd;
        if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) {
-               d->skbpool_hd = skb->next;
-               skb->next = NULL;
+               __skb_unlink(skb, &d->skbpool);
                return skb;
        }
-       if (d->nskbpool < NSKBPOOLMAX
-       && (skb = new_skb(ETH_ZLEN))) {
-               d->nskbpool++;
+       if (skb_queue_len(&d->skbpool) < NSKBPOOLMAX &&
+           (skb = new_skb(ETH_ZLEN)))
                return skb;
-       }
+
        return NULL;
 }
 
@@ -293,29 +286,22 @@ aoecmd_ata_rw(struct aoedev *d)
 
        skb->dev = t->ifp->nd;
        skb = skb_clone(skb, GFP_ATOMIC);
-       if (skb) {
-               if (d->sendq_hd)
-                       d->sendq_tl->next = skb;
-               else
-                       d->sendq_hd = skb;
-               d->sendq_tl = skb;
-       }
+       if (skb)
+               __skb_queue_tail(&d->sendq, skb);
        return 1;
 }
 
 /* some callers cannot sleep, and they can call this function,
  * transmitting the packets later, when interrupts are on
  */
-static struct sk_buff *
-aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
+static void
+aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *queue)
 {
        struct aoe_hdr *h;
        struct aoe_cfghdr *ch;
-       struct sk_buff *skb, *sl, *sl_tail;
+       struct sk_buff *skb;
        struct net_device *ifp;
 
-       sl = sl_tail = NULL;
-
        read_lock(&dev_base_lock);
        for_each_netdev(&init_net, ifp) {
                dev_hold(ifp);
@@ -329,8 +315,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
                }
                skb_put(skb, sizeof *h + sizeof *ch);
                skb->dev = ifp;
-               if (sl_tail == NULL)
-                       sl_tail = skb;
+               __skb_queue_tail(queue, skb);
                h = (struct aoe_hdr *) skb_mac_header(skb);
                memset(h, 0, sizeof *h + sizeof *ch);
 
@@ -342,16 +327,10 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail)
                h->minor = aoeminor;
                h->cmd = AOECMD_CFG;
 
-               skb->next = sl;
-               sl = skb;
 cont:
                dev_put(ifp);
        }
        read_unlock(&dev_base_lock);
-
-       if (tail != NULL)
-               *tail = sl_tail;
-       return sl;
 }
 
 static void
@@ -406,11 +385,7 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
        skb = skb_clone(skb, GFP_ATOMIC);
        if (skb == NULL)
                return;
-       if (d->sendq_hd)
-               d->sendq_tl->next = skb;
-       else
-               d->sendq_hd = skb;
-       d->sendq_tl = skb;
+       __skb_queue_tail(&d->sendq, skb);
 }
 
 static int
@@ -508,16 +483,15 @@ ata_scnt(unsigned char *packet) {
 static void
 rexmit_timer(ulong vp)
 {
+       struct sk_buff_head queue;
        struct aoedev *d;
        struct aoetgt *t, **tt, **te;
        struct aoeif *ifp;
        struct frame *f, *e;
-       struct sk_buff *sl;
        register long timeout;
        ulong flags, n;
 
        d = (struct aoedev *) vp;
-       sl = NULL;
 
        /* timeout is always ~150% of the moving average */
        timeout = d->rttavg;
@@ -589,7 +563,7 @@ rexmit_timer(ulong vp)
                }
        }
 
-       if (d->sendq_hd) {
+       if (!skb_queue_empty(&d->sendq)) {
                n = d->rttavg <<= 1;
                if (n > MAXTIMER)
                        d->rttavg = MAXTIMER;
@@ -600,15 +574,15 @@ rexmit_timer(ulong vp)
                aoecmd_work(d);
        }
 
-       sl = d->sendq_hd;
-       d->sendq_hd = d->sendq_tl = NULL;
+       __skb_queue_head_init(&queue);
+       skb_queue_splice_init(&d->sendq, &queue);
 
        d->timer.expires = jiffies + TIMERTICK;
        add_timer(&d->timer);
 
        spin_unlock_irqrestore(&d->lock, flags);
 
-       aoenet_xmit(sl);
+       aoenet_xmit(&queue);
 }
 
 /* enters with d->lock held */
@@ -767,12 +741,12 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
 void
 aoecmd_ata_rsp(struct sk_buff *skb)
 {
+       struct sk_buff_head queue;
        struct aoedev *d;
        struct aoe_hdr *hin, *hout;
        struct aoe_atahdr *ahin, *ahout;
        struct frame *f;
        struct buf *buf;
-       struct sk_buff *sl;
        struct aoetgt *t;
        struct aoeif *ifp;
        register long n;
@@ -893,21 +867,21 @@ aoecmd_ata_rsp(struct sk_buff *skb)
 
        aoecmd_work(d);
 xmit:
-       sl = d->sendq_hd;
-       d->sendq_hd = d->sendq_tl = NULL;
+       __skb_queue_head_init(&queue);
+       skb_queue_splice_init(&d->sendq, &queue);
 
        spin_unlock_irqrestore(&d->lock, flags);
-       aoenet_xmit(sl);
+       aoenet_xmit(&queue);
 }
 
 void
 aoecmd_cfg(ushort aoemajor, unsigned char aoeminor)
 {
-       struct sk_buff *sl;
-
-       sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL);
+       struct sk_buff_head queue;
 
-       aoenet_xmit(sl);
+       __skb_queue_head_init(&queue);
+       aoecmd_cfg_pkts(aoemajor, aoeminor, &queue);
+       aoenet_xmit(&queue);
 }
  
 struct sk_buff *
@@ -1076,7 +1050,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb)
 
        spin_unlock_irqrestore(&d->lock, flags);
 
-       aoenet_xmit(sl);
+       if (sl) {
+               struct sk_buff_head queue;
+               __skb_queue_head_init(&queue);
+               __skb_queue_tail(&queue, sl);
+               aoenet_xmit(&queue);
+       }
 }
 
 void
index a1d813ab0d6b6046b7d1a1e34ac3d60fd4b68179..75a610adf515006def51ceab921e9b405af5004c 100644 (file)
@@ -188,14 +188,12 @@ skbfree(struct sk_buff *skb)
 static void
 skbpoolfree(struct aoedev *d)
 {
-       struct sk_buff *skb;
+       struct sk_buff *skb, *tmp;
 
-       while ((skb = d->skbpool_hd)) {
-               d->skbpool_hd = skb->next;
-               skb->next = NULL;
+       skb_queue_walk_safe(&d->skbpool, skb, tmp)
                skbfree(skb);
-       }
-       d->skbpool_tl = NULL;
+
+       __skb_queue_head_init(&d->skbpool);
 }
 
 /* find it or malloc it */
@@ -217,6 +215,8 @@ aoedev_by_sysminor_m(ulong sysminor)
                goto out;
        INIT_WORK(&d->work, aoecmd_sleepwork);
        spin_lock_init(&d->lock);
+       skb_queue_head_init(&d->sendq);
+       skb_queue_head_init(&d->skbpool);
        init_timer(&d->timer);
        d->timer.data = (ulong) d;
        d->timer.function = dummy_timer;
index 7b15a5e9cec070a049af569fea2cb9ec51995244..7f83ad90e76fd9f4e971ec4d00826eea2e1cffe7 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/hdreg.h>
 #include <linux/blkdev.h>
 #include <linux/module.h>
+#include <linux/skbuff.h>
 #include "aoe.h"
 
 MODULE_LICENSE("GPL");
index 0c81ca7312878a05b1bc96cbc47d2722ee6b8c37..9157d64270cb041ba8b92bc462913439b12018e0 100644 (file)
@@ -95,13 +95,12 @@ mac_addr(char addr[6])
 }
 
 void
-aoenet_xmit(struct sk_buff *sl)
+aoenet_xmit(struct sk_buff_head *queue)
 {
-       struct sk_buff *skb;
+       struct sk_buff *skb, *tmp;
 
-       while ((skb = sl)) {
-               sl = sl->next;
-               skb->next = skb->prev = NULL;
+       skb_queue_walk_safe(queue, skb, tmp) {
+               __skb_unlink(skb, queue);
                dev_queue_xmit(skb);
        }
 }
index 6a010681ecf3d33f114bb78607e0d6f19d46b319..29ae99817c60a58b0c15ce85a13bf98c3cbdd79a 100644 (file)
@@ -104,6 +104,9 @@ static struct usb_device_id blacklist_table[] = {
        /* Broadcom BCM2046 */
        { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET },
 
+       /* Apple MacBook Pro with Broadcom chip */
+       { USB_DEVICE(0x05ac, 0x820f), .driver_info = BTUSB_RESET },
+
        /* IBM/Lenovo ThinkPad with Broadcom chip */
        { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
        { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU },
@@ -169,6 +172,7 @@ static struct usb_device_id blacklist_table[] = {
 struct btusb_data {
        struct hci_dev       *hdev;
        struct usb_device    *udev;
+       struct usb_interface *intf;
        struct usb_interface *isoc;
 
        spinlock_t lock;
@@ -516,7 +520,7 @@ static int btusb_open(struct hci_dev *hdev)
 
        err = btusb_submit_intr_urb(hdev);
        if (err < 0) {
-               clear_bit(BTUSB_INTR_RUNNING, &hdev->flags);
+               clear_bit(BTUSB_INTR_RUNNING, &data->flags);
                clear_bit(HCI_RUNNING, &hdev->flags);
        }
 
@@ -532,8 +536,10 @@ static int btusb_close(struct hci_dev *hdev)
        if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
                return 0;
 
+       cancel_work_sync(&data->work);
+
        clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
-       usb_kill_anchored_urbs(&data->intr_anchor);
+       usb_kill_anchored_urbs(&data->isoc_anchor);
 
        clear_bit(BTUSB_BULK_RUNNING, &data->flags);
        usb_kill_anchored_urbs(&data->bulk_anchor);
@@ -821,6 +827,7 @@ static int btusb_probe(struct usb_interface *intf,
        }
 
        data->udev = interface_to_usbdev(intf);
+       data->intf = intf;
 
        spin_lock_init(&data->lock);
 
@@ -889,7 +896,7 @@ static int btusb_probe(struct usb_interface *intf,
 
        if (data->isoc) {
                err = usb_driver_claim_interface(&btusb_driver,
-                                                       data->isoc, NULL);
+                                                       data->isoc, data);
                if (err < 0) {
                        hci_free_dev(hdev);
                        kfree(data);
@@ -921,13 +928,22 @@ static void btusb_disconnect(struct usb_interface *intf)
 
        hdev = data->hdev;
 
-       if (data->isoc)
-               usb_driver_release_interface(&btusb_driver, data->isoc);
+       __hci_dev_hold(hdev);
 
-       usb_set_intfdata(intf, NULL);
+       usb_set_intfdata(data->intf, NULL);
+
+       if (data->isoc)
+               usb_set_intfdata(data->isoc, NULL);
 
        hci_unregister_dev(hdev);
 
+       if (intf == data->isoc)
+               usb_driver_release_interface(&btusb_driver, data->intf);
+       else if (data->isoc)
+               usb_driver_release_interface(&btusb_driver, data->isoc);
+
+       __hci_dev_put(hdev);
+
        hci_free_dev(hdev);
 }
 
index 4d37bb312ee3bdd02ed60f90f4d7b7650c9dc993..7938062c1cc7a13daf1306baa659c6cf477782be 100644 (file)
@@ -352,14 +352,14 @@ static int bcsp_flush(struct hci_uart *hu)
 /* Remove ack'ed packets */
 static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
 {
+       struct sk_buff *skb, *tmp;
        unsigned long flags;
-       struct sk_buff *skb;
        int i, pkts_to_be_removed;
        u8 seqno;
 
        spin_lock_irqsave(&bcsp->unack.lock, flags);
 
-       pkts_to_be_removed = bcsp->unack.qlen;
+       pkts_to_be_removed = skb_queue_len(&bcsp->unack);
        seqno = bcsp->msgq_txseq;
 
        while (pkts_to_be_removed) {
@@ -373,19 +373,19 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
                BT_ERR("Peer acked invalid packet");
 
        BT_DBG("Removing %u pkts out of %u, up to seqno %u",
-               pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
+              pkts_to_be_removed, skb_queue_len(&bcsp->unack),
+              (seqno - 1) & 0x07);
 
-       for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
-                       && skb != (struct sk_buff *) &bcsp->unack; i++) {
-               struct sk_buff *nskb;
+       i = 0;
+       skb_queue_walk_safe(&bcsp->unack, skb, tmp) {
+               if (i++ >= pkts_to_be_removed)
+                       break;
 
-               nskb = skb->next;
                __skb_unlink(skb, &bcsp->unack);
                kfree_skb(skb);
-               skb = nskb;
        }
 
-       if (bcsp->unack.qlen == 0)
+       if (skb_queue_empty(&bcsp->unack))
                del_timer(&bcsp->tbcsp);
 
        spin_unlock_irqrestore(&bcsp->unack.lock, flags);
index 1790cc8e431e255ac18c8d8984c99b02fbddde84..8e659914523f76990e1e736201044771531b02eb 100644 (file)
@@ -70,8 +70,8 @@ static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
 {
        unsigned long flags;
        spin_lock_irqsave(&q->lock, flags);
-       /* _urb_unlink needs to know which spinlock to use, thus mb(). */
-       _urb->queue = q; mb(); list_add(&_urb->list, &q->head);
+       /* _urb_unlink needs to know which spinlock to use, thus smp_mb(). */
+       _urb->queue = q; smp_mb(); list_add(&_urb->list, &q->head);
        spin_unlock_irqrestore(&q->lock, flags);
 }
 
@@ -79,8 +79,8 @@ static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
 {
        unsigned long flags;
        spin_lock_irqsave(&q->lock, flags);
-       /* _urb_unlink needs to know which spinlock to use, thus mb(). */
-       _urb->queue = q; mb(); list_add_tail(&_urb->list, &q->head);
+       /* _urb_unlink needs to know which spinlock to use, thus smp_mb(). */
+       _urb->queue = q; smp_mb(); list_add_tail(&_urb->list, &q->head);
        spin_unlock_irqrestore(&q->lock, flags);
 }
 
@@ -89,7 +89,7 @@ static inline void _urb_unlink(struct _urb *_urb)
        struct _urb_queue *q;
        unsigned long flags;
 
-       mb();
+       smp_mb();
        q = _urb->queue;
        /* If q is NULL, it will die at easy-to-debug NULL pointer dereference.
           No need to BUG(). */
index daeb8f76697123bf47015e0145e5a15ccfe86940..e4dce87095410f8f648137ecb992927a6630c483 100644 (file)
@@ -695,13 +695,23 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line)
 {
        struct tty_driver *p, *res = NULL;
        int tty_line = 0;
+       int len;
        char *str;
 
+       for (str = name; *str; str++)
+               if ((*str >= '0' && *str <= '9') || *str == ',')
+                       break;
+       if (!*str)
+               return NULL;
+
+       len = str - name;
+       tty_line = simple_strtoul(str, &str, 10);
+
        mutex_lock(&tty_mutex);
        /* Search through the tty devices to look for a match */
        list_for_each_entry(p, &tty_drivers, tty_drivers) {
-               str = name + strlen(p->name);
-               tty_line = simple_strtoul(str, &str, 10);
+               if (strncmp(name, p->name, len) != 0)
+                       continue;
                if (*str == ',')
                        str++;
                if (*str == '\0')
index 4eee533f3f4af7e8f5c9d811c7ac671d95d05083..71d2ac4e3f46cc0e33410a2d8f7889ac1ae8de09 100644 (file)
@@ -178,11 +178,13 @@ static int verify_pmtmr_rate(void)
 
 /* Number of monotonicity checks to perform during initialization */
 #define ACPI_PM_MONOTONICITY_CHECKS 10
+/* Number of reads we try to get two different values */
+#define ACPI_PM_READ_CHECKS 10000
 
 static int __init init_acpi_pm_clocksource(void)
 {
        cycle_t value1, value2;
-       unsigned int i, j, good = 0;
+       unsigned int i, j = 0;
 
        if (!pmtmr_ioport)
                return -ENODEV;
@@ -192,29 +194,26 @@ static int __init init_acpi_pm_clocksource(void)
 
        /* "verify" this timing source: */
        for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) {
+               udelay(100 * j);
                value1 = clocksource_acpi_pm.read();
-               for (i = 0; i < 10000; i++) {
+               for (i = 0; i < ACPI_PM_READ_CHECKS; i++) {
                        value2 = clocksource_acpi_pm.read();
                        if (value2 == value1)
                                continue;
                        if (value2 > value1)
-                               good++;
                                break;
                        if ((value2 < value1) && ((value2) < 0xFFF))
-                               good++;
                                break;
                        printk(KERN_INFO "PM-Timer had inconsistent results:"
                               " 0x%#llx, 0x%#llx - aborting.\n",
                               value1, value2);
                        return -EINVAL;
                }
-               udelay(300 * i);
-       }
-
-       if (good != ACPI_PM_MONOTONICITY_CHECKS) {
-               printk(KERN_INFO "PM-Timer failed consistency check "
-                      " (0x%#llx) - aborting.\n", value1);
-               return -ENODEV;
+               if (i == ACPI_PM_READ_CHECKS) {
+                       printk(KERN_INFO "PM-Timer failed consistency check "
+                              " (0x%#llx) - aborting.\n", value1);
+                       return -ENODEV;
+               }
        }
 
        if (verify_pmtmr_rate() != 0)
index ee827a7f7c6a48257e5af20219dcb256421d8994..b6ad3ac5916e0311d989fb3241b04f6327b62912 100644 (file)
@@ -1157,6 +1157,8 @@ static int aead_authenc_givencrypt(
        edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT;
 
        memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc));
+       /* avoid consecutive packets going out with same IV */
+       *(__be64 *)req->giv ^= cpu_to_be64(req->seq);
 
        return ipsec_esp(edesc, areq, req->giv, req->seq,
                         ipsec_esp_encrypt_done);
@@ -1449,6 +1451,8 @@ static int talitos_probe(struct of_device *ofdev,
 
        priv->ofdev = ofdev;
 
+       INIT_LIST_HEAD(&priv->alg_list);
+
        tasklet_init(&priv->done_task, talitos_done, (unsigned long)dev);
        tasklet_init(&priv->error_task, talitos_error, (unsigned long)dev);
 
@@ -1575,8 +1579,6 @@ static int talitos_probe(struct of_device *ofdev,
        }
 
        /* register crypto algorithms the device supports */
-       INIT_LIST_HEAD(&priv->alg_list);
-
        for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
                if (hw_supports(dev, driver_algs[i].desc_hdr_template)) {
                        struct talitos_crypto_alg *t_alg;
index ce8d94fbfd7e24b584da17e743fd729d30971e18..bfda8c80ef2473923a1ff1e38db845252b0bb16b 100644 (file)
@@ -69,7 +69,7 @@ static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value)
        return i2c_smbus_write_byte_data(client, reg, value);
 }
 
-struct ad7414_data *ad7414_update_device(struct device *dev)
+static struct ad7414_data *ad7414_update_device(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct ad7414_data *data = i2c_get_clientdata(client);
index d191118ba0cbc2964b288492abed58be4022c91c..d6b490d3e36f029660e079f6f42802329cd4bf4b 100644 (file)
@@ -31,7 +31,7 @@
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
-MODULE_VERSION("0.6.2");
+MODULE_VERSION("0.6.3");
 MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
 
 #define ATXP1_VID      0x00
@@ -289,16 +289,16 @@ static int atxp1_detect(struct i2c_client *new_client, int kind,
        if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) &&
             (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) &&
             (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) &&
-            (i2c_smbus_read_byte_data(new_client, 0xff) == 0) )) {
+            (i2c_smbus_read_byte_data(new_client, 0xff) == 0)))
+               return -ENODEV;
 
-               /* No vendor ID, now checking if registers 0x10,0x11 (non-existent)
-                * showing the same as register 0x00 */
-               temp = i2c_smbus_read_byte_data(new_client, 0x00);
+       /* No vendor ID, now checking if registers 0x10,0x11 (non-existent)
+        * showing the same as register 0x00 */
+       temp = i2c_smbus_read_byte_data(new_client, 0x00);
 
-               if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) &&
-                        (i2c_smbus_read_byte_data(new_client, 0x11) == temp) ))
-                       return -ENODEV;
-       }
+       if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) &&
+             (i2c_smbus_read_byte_data(new_client, 0x11) == temp)))
+               return -ENODEV;
 
        /* Get VRM */
        temp = vid_which_vrm();
index 30cdb0956779646d311476078a9c30ebc6f643ca..f1133081cc42789b642a9e11c76c5efa6749a618 100644 (file)
@@ -273,10 +273,10 @@ struct it87_data {
 static inline int has_16bit_fans(const struct it87_data *data)
 {
        /* IT8705F Datasheet 0.4.1, 3h == Version G.
-          IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I.
+          IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J.
           These are the first revisions with 16bit tachometer support. */
        return (data->type == it87 && data->revision >= 0x03)
-           || (data->type == it8712 && data->revision >= 0x07)
+           || (data->type == it8712 && data->revision >= 0x08)
            || data->type == it8716
            || data->type == it8718;
 }
index 22f6d5c00d80e85829dc5d81133cc5cb2f9c6029..0e7b1c6724aa5e0059deede2ca40f3cf5fcd89e8 100644 (file)
@@ -180,7 +180,7 @@ static const struct i2c_algorithm i2c_powermac_algorithm = {
 };
 
 
-static int i2c_powermac_remove(struct platform_device *dev)
+static int __devexit i2c_powermac_remove(struct platform_device *dev)
 {
        struct i2c_adapter      *adapter = platform_get_drvdata(dev);
        struct pmac_i2c_bus     *bus = i2c_get_adapdata(adapter);
@@ -200,7 +200,7 @@ static int i2c_powermac_remove(struct platform_device *dev)
 }
 
 
-static int __devexit i2c_powermac_probe(struct platform_device *dev)
+static int __devinit i2c_powermac_probe(struct platform_device *dev)
 {
        struct pmac_i2c_bus *bus = dev->dev.platform_data;
        struct device_node *parent = NULL;
index af4491fa7e347c3059b50d6bf68d509cdb24ea5b..307d976c9b69b977c389e62abfbe43682b1d3e24 100644 (file)
@@ -583,8 +583,10 @@ static int __init i2c_dev_init(void)
                goto out;
 
        i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");
-       if (IS_ERR(i2c_dev_class))
+       if (IS_ERR(i2c_dev_class)) {
+               res = PTR_ERR(i2c_dev_class);
                goto out_unreg_chrdev;
+       }
 
        res = i2c_add_driver(&i2cdev_driver);
        if (res)
index fc735ab08ff4f8f3f80c82e911242a2f54f84758..8e93a797c93de9c8eaf35e28573a6e81dc18dda3 100644 (file)
@@ -292,6 +292,20 @@ config IDE_GENERIC
        tristate "generic/default IDE chipset support"
        depends on ALPHA || X86 || IA64 || M32R || MIPS
        help
+         This is the generic IDE driver.  This driver attaches to the
+         fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
+         so on).  Please note that if this driver is built into the
+         kernel or loaded before other ATA (IDE or libata) drivers
+         and the controller is located at legacy ports, this driver
+         may grab those ports and thus can prevent the controller
+         specific driver from attaching.
+
+         Also, currently, IDE generic doesn't allow IRQ sharing
+         meaning that the IRQs it grabs won't be available to other
+         controllers sharing those IRQs which usually makes drivers
+         for those controllers fail.  Generally, it's not a good idea
+         to load IDE generic driver on modern systems.
+
          If unsure, say N.
 
 config BLK_DEV_PLATFORM
index f1489999cf916a53f222a9c71d9e518be9f69c20..49a8c589e346c15982e158e5116c9fd930aa9b46 100644 (file)
@@ -1933,7 +1933,6 @@ static void ide_cd_remove(ide_drive_t *drive)
 
        ide_proc_unregister_driver(drive, info->driver);
 
-       blk_unregister_filter(info->disk);
        del_gendisk(info->disk);
 
        ide_cd_put(info);
@@ -2159,7 +2158,6 @@ static int ide_cd_probe(ide_drive_t *drive)
        g->fops = &idecd_ops;
        g->flags |= GENHD_FL_REMOVABLE;
        add_disk(g);
-       blk_register_filter(g);
        return 0;
 
 out_free_cd:
index 1bce84b566304115c2834a1742f03284e2c25ce9..3833189144edd507de0c26339ca8687ed734dedc 100644 (file)
@@ -2338,7 +2338,7 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
 {
        idetape_tape_t *tape = drive->driver_data;
        struct ide_atapi_pc pc;
-       char fw_rev[6], vendor_id[10], product_id[18];
+       char fw_rev[4], vendor_id[8], product_id[16];
 
        idetape_create_inquiry_cmd(&pc);
        if (idetape_queue_pc_tail(drive, &pc)) {
@@ -2350,11 +2350,11 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
        memcpy(product_id, &pc.buf[16], 16);
        memcpy(fw_rev, &pc.buf[32], 4);
 
-       ide_fixstring(vendor_id, 10, 0);
-       ide_fixstring(product_id, 18, 0);
-       ide_fixstring(fw_rev, 6, 0);
+       ide_fixstring(vendor_id, 8, 0);
+       ide_fixstring(product_id, 16, 0);
+       ide_fixstring(fw_rev, 4, 0);
 
-       printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n",
+       printk(KERN_INFO "ide-tape: %s <-> %s: %.8s %.16s rev %.4s\n",
                        drive->name, tape->name, vendor_id, product_id, fw_rev);
 }
 
index badf79fc9e3a1c67c3eef99bbbce4cb9c31eb355..39c9ee995857fcf5187b08b2526c14bc25b8de26 100644 (file)
@@ -107,6 +107,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
 
        base = ioremap(offset, size);
 
+       memset(&hw, 0, sizeof(hw));
        for (i = 0; i <= 7; i++)
                hw.io_ports_array[i] =
                                (unsigned long)(base + ((0x1f0 + i) << 5));
index eb107eef0dbc8e89cac9a5604b5fe0619165f4d3..c37ab17438193aa492688f2ac34c2e7245ade703 100644 (file)
@@ -613,6 +613,14 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
        return 0;
 }
 
+static struct hpt_info *hpt3xx_get_info(struct device *dev)
+{
+       struct ide_host *host   = dev_get_drvdata(dev);
+       struct hpt_info *info   = (struct hpt_info *)host->host_priv;
+
+       return dev == host->dev[1] ? info + 1 : info;
+}
+
 /*
  * The Marvell bridge chips used on the HighPoint SATA cards do not seem
  * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes...
@@ -621,9 +629,7 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list)
 static u8 hpt3xx_udma_filter(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
-       struct pci_dev *dev     = to_pci_dev(hwif->dev);
-       struct ide_host *host   = pci_get_drvdata(dev);
-       struct hpt_info *info   = host->host_priv + (hwif->dev == host->dev[1]);
+       struct hpt_info *info   = hpt3xx_get_info(hwif->dev);
        u8 mask                 = hwif->ultra_mask;
 
        switch (info->chip_type) {
@@ -662,9 +668,7 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive)
 static u8 hpt3xx_mdma_filter(ide_drive_t *drive)
 {
        ide_hwif_t *hwif        = HWIF(drive);
-       struct pci_dev *dev     = to_pci_dev(hwif->dev);
-       struct ide_host *host   = pci_get_drvdata(dev);
-       struct hpt_info *info   = host->host_priv + (hwif->dev == host->dev[1]);
+       struct hpt_info *info   = hpt3xx_get_info(hwif->dev);
 
        switch (info->chip_type) {
        case HPT372 :
@@ -700,8 +704,7 @@ static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed)
 {
        ide_hwif_t *hwif        = drive->hwif;
        struct pci_dev *dev     = to_pci_dev(hwif->dev);
-       struct ide_host *host   = pci_get_drvdata(dev);
-       struct hpt_info *info   = host->host_priv + (hwif->dev == host->dev[1]);
+       struct hpt_info *info   = hpt3xx_get_info(hwif->dev);
        struct hpt_timings *t   = info->timings;
        u8  itr_addr            = 0x40 + (drive->dn * 4);
        u32 old_itr             = 0;
@@ -744,8 +747,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
 {
        ide_hwif_t *hwif        = HWIF(drive);
        struct pci_dev  *dev    = to_pci_dev(hwif->dev);
-       struct ide_host *host   = pci_get_drvdata(dev);
-       struct hpt_info *info   = host->host_priv + (hwif->dev == host->dev[1]);
+       struct hpt_info *info   = hpt3xx_get_info(hwif->dev);
 
        if (drive->quirk_list) {
                if (info->chip_type >= HPT370) {
@@ -973,8 +975,7 @@ static int __devinit hpt37x_calibrate_dpll(struct pci_dev *dev, u16 f_low, u16 f
 static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev)
 {
        unsigned long io_base   = pci_resource_start(dev, 4);
-       struct ide_host *host   = pci_get_drvdata(dev);
-       struct hpt_info *info   = host->host_priv + (&dev->dev == host->dev[1]);
+       struct hpt_info *info   = hpt3xx_get_info(&dev->dev);
        const char *name        = DRV_NAME;
        u8 pci_clk,  dpll_clk   = 0;    /* PCI and DPLL clock in MHz */
        u8 chip_type;
@@ -1217,8 +1218,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev)
 static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
 {
        struct pci_dev  *dev    = to_pci_dev(hwif->dev);
-       struct ide_host *host   = pci_get_drvdata(dev);
-       struct hpt_info *info   = host->host_priv + (hwif->dev == host->dev[1]);
+       struct hpt_info *info   = hpt3xx_get_info(hwif->dev);
        u8 chip_type            = info->chip_type;
        u8 scr1 = 0, ata66      = hwif->channel ? 0x01 : 0x02;
 
@@ -1262,8 +1262,7 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif)
 static void __devinit init_hwif_hpt366(ide_hwif_t *hwif)
 {
        struct pci_dev *dev     = to_pci_dev(hwif->dev);
-       struct ide_host *host   = pci_get_drvdata(dev);
-       struct hpt_info *info   = host->host_priv + (hwif->dev == host->dev[1]);
+       struct hpt_info *info   = hpt3xx_get_info(hwif->dev);
        int serialize           = HPT_SERIALIZE_IO;
        u8  chip_type           = info->chip_type;
        u8  new_mcr, old_mcr    = 0;
index f29dbb767e87c3c0f77b5f23c8c58de06e85c169..9559248f265b80090aeecd8c693059e9e43bdad0 100644 (file)
@@ -1342,6 +1342,12 @@ static __be32 convert_access(int acc)
 static void set_fmr_seg(struct mlx4_wqe_fmr_seg *fseg, struct ib_send_wr *wr)
 {
        struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(wr->wr.fast_reg.page_list);
+       int i;
+
+       for (i = 0; i < wr->wr.fast_reg.page_list_len; ++i)
+               wr->wr.fast_reg.page_list->page_list[i] =
+                       cpu_to_be64(wr->wr.fast_reg.page_list->page_list[i] |
+                                   MLX4_MTT_FLAG_PRESENT);
 
        fseg->flags             = convert_access(wr->wr.fast_reg.access_flags);
        fseg->mem_key           = cpu_to_be32(wr->wr.fast_reg.rkey);
index 9f0b964b2c9932af7567dcae6efc7d98c6c01728..499d3cf83e1f28e2ee263ed3e92e2fdb18d1f59b 100644 (file)
@@ -1956,13 +1956,6 @@ static int mini_cm_reject(struct nes_cm_core *cm_core,
                return ret;
        cleanup_retrans_entry(cm_node);
        cm_node->state = NES_CM_STATE_CLOSED;
-       ret = send_fin(cm_node, NULL);
-
-       if (cm_node->accept_pend) {
-               BUG_ON(!cm_node->listener);
-               atomic_dec(&cm_node->listener->pend_accepts_cnt);
-               BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0);
-       }
 
        ret = send_reset(cm_node, NULL);
        return ret;
@@ -2383,6 +2376,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp)
                        atomic_inc(&cm_disconnects);
                        cm_event.event = IW_CM_EVENT_DISCONNECT;
                        if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) {
+                               issued_disconnect_reset = 1;
                                cm_event.status = IW_CM_EVENT_STATUS_RESET;
                                nes_debug(NES_DBG_CM, "Generating a CM "
                                        "Disconnect Event (status reset) for "
@@ -2508,7 +2502,6 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt)
                nes_debug(NES_DBG_CM, "Call close API\n");
 
                g_cm_core->api->close(g_cm_core, nesqp->cm_node);
-               nesqp->cm_node = NULL;
        }
 
        return ret;
@@ -2837,6 +2830,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
        cm_node->apbvt_set = 1;
        nesqp->cm_node = cm_node;
        cm_node->nesqp = nesqp;
+       nes_add_ref(&nesqp->ibqp);
 
        return 0;
 }
@@ -3167,7 +3161,6 @@ static void cm_event_connect_error(struct nes_cm_event *event)
        if (ret)
                printk(KERN_ERR "%s[%u] OFA CM event_handler returned, "
                        "ret=%d\n", __func__, __LINE__, ret);
-       nes_rem_ref(&nesqp->ibqp);
        cm_id->rem_ref(cm_id);
 
        rem_ref_cm_node(event->cm_node->cm_core, event->cm_node);
index b0ffc9abe8c082fa1c32e112e8aa50d9e06bca83..05eb41b8ab631692fcd46686eedc0940443236c9 100644 (file)
@@ -293,6 +293,7 @@ struct ipoib_dev_priv {
 
        struct delayed_work pkey_poll_task;
        struct delayed_work mcast_task;
+       struct work_struct carrier_on_task;
        struct work_struct flush_light;
        struct work_struct flush_normal;
        struct work_struct flush_heavy;
@@ -464,6 +465,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port);
 void ipoib_dev_cleanup(struct net_device *dev);
 
 void ipoib_mcast_join_task(struct work_struct *work);
+void ipoib_mcast_carrier_on_task(struct work_struct *work);
 void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb);
 
 void ipoib_mcast_restart_task(struct work_struct *work);
index 7e9e218738fa0f4be74741266e690d7c4211e6e0..e9ca3cb57d5219960f9f67adf7eadb19dabc206e 100644 (file)
@@ -404,7 +404,7 @@ static void path_rec_completion(int status,
        struct net_device *dev = path->dev;
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        struct ipoib_ah *ah = NULL;
-       struct ipoib_ah *old_ah;
+       struct ipoib_ah *old_ah = NULL;
        struct ipoib_neigh *neigh, *tn;
        struct sk_buff_head skqueue;
        struct sk_buff *skb;
@@ -428,12 +428,12 @@ static void path_rec_completion(int status,
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       old_ah   = path->ah;
-       path->ah = ah;
-
        if (ah) {
                path->pathrec = *pathrec;
 
+               old_ah   = path->ah;
+               path->ah = ah;
+
                ipoib_dbg(priv, "created address handle %p for LID 0x%04x, SL %d\n",
                          ah, be16_to_cpu(pathrec->dlid), pathrec->sl);
 
@@ -1075,6 +1075,7 @@ static void ipoib_setup(struct net_device *dev)
 
        INIT_DELAYED_WORK(&priv->pkey_poll_task, ipoib_pkey_poll);
        INIT_DELAYED_WORK(&priv->mcast_task,   ipoib_mcast_join_task);
+       INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task);
        INIT_WORK(&priv->flush_light,   ipoib_ib_dev_flush_light);
        INIT_WORK(&priv->flush_normal,   ipoib_ib_dev_flush_normal);
        INIT_WORK(&priv->flush_heavy,   ipoib_ib_dev_flush_heavy);
index ac33c8f3ea8580e5120dd98704cfbccb0ccd5c71..aae28620a6e5f01a3650ce59b5c8d35f65b4ca28 100644 (file)
@@ -366,6 +366,21 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
        return ret;
 }
 
+void ipoib_mcast_carrier_on_task(struct work_struct *work)
+{
+       struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv,
+                                                  carrier_on_task);
+
+       /*
+        * Take rtnl_lock to avoid racing with ipoib_stop() and
+        * turning the carrier back on while a device is being
+        * removed.
+        */
+       rtnl_lock();
+       netif_carrier_on(priv->dev);
+       rtnl_unlock();
+}
+
 static int ipoib_mcast_join_complete(int status,
                                     struct ib_sa_multicast *multicast)
 {
@@ -392,16 +407,12 @@ static int ipoib_mcast_join_complete(int status,
                                           &priv->mcast_task, 0);
                mutex_unlock(&mcast_mutex);
 
-               if (mcast == priv->broadcast) {
-                       /*
-                        * Take RTNL lock here to avoid racing with
-                        * ipoib_stop() and turning the carrier back
-                        * on while a device is being removed.
-                        */
-                       rtnl_lock();
-                       netif_carrier_on(dev);
-                       rtnl_unlock();
-               }
+               /*
+                * Defer carrier on work to ipoib_workqueue to avoid a
+                * deadlock on rtnl_lock here.
+                */
+               if (mcast == priv->broadcast)
+                       queue_work(ipoib_workqueue, &priv->carrier_on_task);
 
                return 0;
        }
index 18f4d7f6ce6d0d3b983d34fffc7b6da437679cc7..2998a6ac9ae44f82aa4a61f88ccda12de56bf71e 100644 (file)
@@ -351,8 +351,9 @@ static int report_tp_state(struct bcm5974 *dev, int size)
 #define BCM5974_WELLSPRING_MODE_REQUEST_VALUE          0x300
 #define BCM5974_WELLSPRING_MODE_REQUEST_INDEX          0
 #define BCM5974_WELLSPRING_MODE_VENDOR_VALUE           0x01
+#define BCM5974_WELLSPRING_MODE_NORMAL_VALUE           0x08
 
-static int bcm5974_wellspring_mode(struct bcm5974 *dev)
+static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on)
 {
        char *data = kmalloc(8, GFP_KERNEL);
        int retval = 0, size;
@@ -377,7 +378,9 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev)
        }
 
        /* apply the mode switch */
-       data[0] = BCM5974_WELLSPRING_MODE_VENDOR_VALUE;
+       data[0] = on ?
+               BCM5974_WELLSPRING_MODE_VENDOR_VALUE :
+               BCM5974_WELLSPRING_MODE_NORMAL_VALUE;
 
        /* write configuration */
        size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
@@ -392,7 +395,8 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev)
                goto out;
        }
 
-       dprintk(2, "bcm5974: switched to wellspring mode.\n");
+       dprintk(2, "bcm5974: switched to %s mode.\n",
+               on ? "wellspring" : "normal");
 
  out:
        kfree(data);
@@ -481,7 +485,7 @@ exit:
  */
 static int bcm5974_start_traffic(struct bcm5974 *dev)
 {
-       if (bcm5974_wellspring_mode(dev)) {
+       if (bcm5974_wellspring_mode(dev, true)) {
                dprintk(1, "bcm5974: mode switch failed\n");
                goto error;
        }
@@ -504,6 +508,7 @@ static void bcm5974_pause_traffic(struct bcm5974 *dev)
 {
        usb_kill_urb(dev->tp_urb);
        usb_kill_urb(dev->bt_urb);
+       bcm5974_wellspring_mode(dev, false);
 }
 
 /*
index bf44f9d68342bdcd41f4b63ed87737d60e8f70cf..c8b7e8a45c4d91292c09afeb239be90efe598c79 100644 (file)
@@ -119,8 +119,8 @@ static int __devinit jornada720_ts_probe(struct platform_device *pdev)
        input_dev->id.bustype = BUS_HOST;
        input_dev->dev.parent = &pdev->dev;
 
-       input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
-       input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH);
+       input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
        input_set_abs_params(input_dev, ABS_X, 270, 3900, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 180, 3700, 0, 0);
 
index 75726ea0fbbd1615705f68ab58bb914df386cf97..5360c4fd473915c8ad79bbd80de870b321c3f7f9 100644 (file)
@@ -828,15 +828,18 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
                        return -ESRCH;
                if (card->load_firmware == NULL) {
                        printk(KERN_DEBUG "kcapi: load: no load function\n");
+                       capi_ctr_put(card);
                        return -ESRCH;
                }
 
                if (ldef.t4file.len <= 0) {
                        printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len);
+                       capi_ctr_put(card);
                        return -EINVAL;
                }
                if (ldef.t4file.data == NULL) {
                        printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n");
+                       capi_ctr_put(card);
                        return -EINVAL;
                }
 
@@ -849,6 +852,7 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
 
                if (card->cardstate != CARD_DETECTED) {
                        printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr);
+                       capi_ctr_put(card);
                        return -EBUSY;
                }
                card->cardstate = CARD_LOADING;
index fd2c9be6d8492a14076781408735f67c3e9cef47..5783d22a18fe0f4d5201b5bca21a28ae8be43944 100644 (file)
 #define D_FREG_MASK  0xF
 
 struct zt {
-       unsigned short z1;  /* Z1 pointer 16 Bit */
-       unsigned short z2;  /* Z2 pointer 16 Bit */
+       __le16 z1;  /* Z1 pointer 16 Bit */
+       __le16 z2;  /* Z2 pointer 16 Bit */
 };
 
 struct dfifo {
index 9cf5edbb1a9b119db51d1b60494b3767886184d8..cd8302af40ebace556b7dc5dc89b1465c0ac3dd3 100644 (file)
@@ -43,7 +43,7 @@ MODULE_LICENSE("GPL");
 module_param(debug, uint, 0);
 
 static LIST_HEAD(HFClist);
-DEFINE_RWLOCK(HFClock);
+static DEFINE_RWLOCK(HFClock);
 
 enum {
        HFC_CCD_2BD0,
@@ -88,7 +88,7 @@ struct hfcPCI_hw {
        unsigned char           bswapped;
        unsigned char           protocol;
        int                     nt_timer;
-       unsigned char           *pci_io; /* start of PCI IO memory */
+       unsigned char __iomem   *pci_io; /* start of PCI IO memory */
        dma_addr_t              dmahandle;
        void                    *fifos; /* FIFO memory */
        int                     last_bfifo_cnt[2];
@@ -153,7 +153,7 @@ release_io_hfcpci(struct hfc_pci *hc)
        pci_write_config_word(hc->pdev, PCI_COMMAND, 0);
        del_timer(&hc->hw.timer);
        pci_free_consistent(hc->pdev, 0x8000, hc->hw.fifos, hc->hw.dmahandle);
-       iounmap((void *)hc->hw.pci_io);
+       iounmap(hc->hw.pci_io);
 }
 
 /*
@@ -366,8 +366,7 @@ static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo)
        bzt->f2 = MAX_B_FRAMES;
        bzt->f1 = bzt->f2;      /* init F pointers to remain constant */
        bzt->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1);
-       bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16(
-           le16_to_cpu(bzt->za[MAX_B_FRAMES].z1 - 1));
+       bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 2);
        if (fifo_state)
                hc->hw.fifo_en |= fifo_state;
        Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en);
@@ -482,7 +481,7 @@ receive_dmsg(struct hfc_pci *hc)
                        df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
                            (MAX_D_FRAMES + 1); /* next buffer */
                        df->za[df->f2 & D_FREG_MASK].z2 =
-                           cpu_to_le16((zp->z2 + rcnt) & (D_FIFO_SIZE - 1));
+                           cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) & (D_FIFO_SIZE - 1));
                } else {
                        dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC);
                        if (!dch->rx_skb) {
@@ -523,10 +522,10 @@ receive_dmsg(struct hfc_pci *hc)
 /*
  * check for transparent receive data and read max one threshold size if avail
  */
-int
+static int
 hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
 {
-       unsigned short  *z1r, *z2r;
+        __le16 *z1r, *z2r;
        int             new_z2, fcnt, maxlen;
        u_char          *ptr, *ptr1;
 
@@ -576,7 +575,7 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
 /*
  * B-channel main receive routine
  */
-void
+static void
 main_rec_hfcpci(struct bchannel *bch)
 {
        struct hfc_pci  *hc = bch->hw;
@@ -724,7 +723,7 @@ hfcpci_fill_fifo(struct bchannel *bch)
        struct bzfifo   *bz;
        u_char          *bdata;
        u_char          new_f1, *src, *dst;
-       unsigned short  *z1t, *z2t;
+       __le16 *z1t, *z2t;
 
        if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
                printk(KERN_DEBUG "%s\n", __func__);
@@ -1679,7 +1678,7 @@ hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb)
  * called for card init message
  */
 
-void
+static void
 inithfcpci(struct hfc_pci *hc)
 {
        printk(KERN_DEBUG "inithfcpci: entered\n");
@@ -1966,7 +1965,7 @@ setup_hw(struct hfc_pci *hc)
                printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
                return 1;
        }
-       hc->hw.pci_io = (char *)(ulong)hc->pdev->resource[1].start;
+       hc->hw.pci_io = (char __iomem *)(unsigned long)hc->pdev->resource[1].start;
 
        if (!hc->hw.pci_io) {
                printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
index 127cfdad68e7bb8b4ec727acb7e8cab9462e5e8e..77c280ef2eb64ddbb81cff6b78c40bcf7e302b3e 100644 (file)
@@ -1533,8 +1533,10 @@ static int isdn_ppp_mp_bundle_array_init(void)
        int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
        if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL )
                return -ENOMEM;
-       for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
+       for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
                spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
+               skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags);
+       }
        return 0;
 }
 
@@ -1567,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
                if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
                        return -ENOMEM;
                lp->next = lp->last = lp;       /* nobody else in a queue */
-               lp->netdev->pb->frags = NULL;
+               skb_queue_head_init(&lp->netdev->pb->frags);
                lp->netdev->pb->frames = 0;
                lp->netdev->pb->seq = UINT_MAX;
        }
@@ -1579,28 +1581,29 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to )
 
 static u32 isdn_ppp_mp_get_seq( int short_seq, 
                                        struct sk_buff * skb, u32 last_seq );
-static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
-                       struct sk_buff * from, struct sk_buff * to );
-static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
-                               struct sk_buff * from, struct sk_buff * to );
-static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
+static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from,
+                               struct sk_buff *to);
+static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
+                                  struct sk_buff *from, struct sk_buff *to,
+                                  u32 lastseq);
+static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb);
 static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
 
 static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, 
-                                                       struct sk_buff *skb)
+                               struct sk_buff *skb)
 {
-       struct ippp_struct *is;
-       isdn_net_local * lpq;
-       ippp_bundle * mp;
-       isdn_mppp_stats * stats;
-       struct sk_buff * newfrag, * frag, * start, *nextf;
+       struct sk_buff *newfrag, *frag, *start, *nextf;
        u32 newseq, minseq, thisseq;
+       isdn_mppp_stats *stats;
+       struct ippp_struct *is;
        unsigned long flags;
+       isdn_net_local *lpq;
+       ippp_bundle *mp;
        int slot;
 
        spin_lock_irqsave(&net_dev->pb->lock, flags);
-       mp = net_dev->pb;
-        stats = &mp->stats;
+       mp = net_dev->pb;
+       stats = &mp->stats;
        slot = lp->ppp_slot;
        if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
                printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
@@ -1611,20 +1614,19 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                return;
        }
        is = ippp_table[slot];
-       if( ++mp->frames > stats->max_queue_len )
+       if (++mp->frames > stats->max_queue_len)
                stats->max_queue_len = mp->frames;
-       
+
        if (is->debug & 0x8)
                isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
 
-       newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, 
-                                               skb, is->last_link_seqno);
-
+       newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
+                                    skb, is->last_link_seqno);
 
        /* if this packet seq # is less than last already processed one,
         * toss it right away, but check for sequence start case first 
         */
-       if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) {
+       if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) {
                mp->seq = newseq;       /* the first packet: required for
                                         * rfc1990 non-compliant clients --
                                         * prevents constant packet toss */
@@ -1634,7 +1636,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                spin_unlock_irqrestore(&mp->lock, flags);
                return;
        }
-       
+
        /* find the minimum received sequence number over all links */
        is->last_link_seqno = minseq = newseq;
        for (lpq = net_dev->queue;;) {
@@ -1655,22 +1657,31 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                                         * packets */
        newfrag = skb;
 
-       /* if this new fragment is before the first one, then enqueue it now. */
-       if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
-               newfrag->next = frag;
-               mp->frags = frag = newfrag;
-               newfrag = NULL;
-       }
+       /* Insert new fragment into the proper sequence slot.  */
+       skb_queue_walk(&mp->frags, frag) {
+               if (MP_SEQ(frag) == newseq) {
+                       isdn_ppp_mp_free_skb(mp, newfrag);
+                       newfrag = NULL;
+                       break;
+               }
+               if (MP_LT(newseq, MP_SEQ(frag))) {
+                       __skb_queue_before(&mp->frags, frag, newfrag);
+                       newfrag = NULL;
+                       break;
+               }
+       }
+       if (newfrag)
+               __skb_queue_tail(&mp->frags, newfrag);
 
-       start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
-                               MP_SEQ(frag) == mp->seq ? frag : NULL;
+       frag = skb_peek(&mp->frags);
+       start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) &&
+                (MP_SEQ(frag) == mp->seq)) ? frag : NULL;
+       if (!start)
+               goto check_overflow;
 
-       /* 
-        * main fragment traversing loop
+       /* main fragment traversing loop
         *
         * try to accomplish several tasks:
-        * - insert new fragment into the proper sequence slot (once that's done
-        *   newfrag will be set to NULL)
         * - reassemble any complete fragment sequence (non-null 'start'
         *   indicates there is a continguous sequence present)
         * - discard any incomplete sequences that are below minseq -- due
@@ -1679,71 +1690,46 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
         *   come to complete such sequence and it should be discarded
         *
         * loop completes when we accomplished the following tasks:
-        * - new fragment is inserted in the proper sequence ('newfrag' is 
-        *   set to NULL)
         * - we hit a gap in the sequence, so no reassembly/processing is 
         *   possible ('start' would be set to NULL)
         *
         * algorithm for this code is derived from code in the book
         * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
         */
-       while (start != NULL || newfrag != NULL) {
-
-               thisseq = MP_SEQ(frag);
-               nextf = frag->next;
-
-               /* drop any duplicate fragments */
-               if (newfrag != NULL && thisseq == newseq) {
-                       isdn_ppp_mp_free_skb(mp, newfrag);
-                       newfrag = NULL;
-               }
-
-               /* insert new fragment before next element if possible. */
-               if (newfrag != NULL && (nextf == NULL || 
-                                               MP_LT(newseq, MP_SEQ(nextf)))) {
-                       newfrag->next = nextf;
-                       frag->next = nextf = newfrag;
-                       newfrag = NULL;
-               }
-
-               if (start != NULL) {
-                       /* check for misplaced start */
-                       if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
-                               printk(KERN_WARNING"isdn_mppp(seq %d): new "
-                                     "BEGIN flag with no prior END", thisseq);
-                               stats->seqerrs++;
-                               stats->frame_drops++;
-                               start = isdn_ppp_mp_discard(mp, start,frag);
-                               nextf = frag->next;
-                       }
-               } else if (MP_LE(thisseq, minseq)) {            
-                       if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
+       skb_queue_walk_safe(&mp->frags, frag, nextf) {
+               thisseq = MP_SEQ(frag);
+
+               /* check for misplaced start */
+               if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
+                       printk(KERN_WARNING"isdn_mppp(seq %d): new "
+                              "BEGIN flag with no prior END", thisseq);
+                       stats->seqerrs++;
+                       stats->frame_drops++;
+                       isdn_ppp_mp_discard(mp, start, frag);
+                       start = frag;
+               } else if (MP_LE(thisseq, minseq)) {            
+                       if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
                                start = frag;
-                       else {
+                       else {
                                if (MP_FLAGS(frag) & MP_END_FRAG)
-                                       stats->frame_drops++;
-                               if( mp->frags == frag )
-                                       mp->frags = nextf;      
+                                       stats->frame_drops++;
+                               __skb_unlink(skb, &mp->frags);
                                isdn_ppp_mp_free_skb(mp, frag);
-                               frag = nextf;
                                continue;
-                       }
+                       }
                }
-               
-               /* if start is non-null and we have end fragment, then
-                * we have full reassembly sequence -- reassemble 
-                * and process packet now
+
+               /* if we have end fragment, then we have full reassembly
+                * sequence -- reassemble and process packet now
                 */
-               if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
-                       minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
-                       /* Reassemble the packet then dispatch it */
-                       isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
-      
-                       start = NULL;
-                       frag = NULL;
+               if (MP_FLAGS(frag) & MP_END_FRAG) {
+                       minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
+                       /* Reassemble the packet then dispatch it */
+                       isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq);
 
-                       mp->frags = nextf;
-               }
+                       start = NULL;
+                       frag = NULL;
+               }
 
                /* check if need to update start pointer: if we just
                 * reassembled the packet and sequence is contiguous
@@ -1754,26 +1740,25 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                 * below low watermark and set start to the next frag or
                 * clear start ptr.
                 */ 
-               if (nextf != NULL && 
+               if (nextf != (struct sk_buff *)&mp->frags && 
                    ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
-                       /* if we just reassembled and the next one is here, 
-                        * then start another reassembly. */
-
-                       if (frag == NULL) {
+                       /* if we just reassembled and the next one is here, 
+                        * then start another reassembly.
+                        */
+                       if (frag == NULL) {
                                if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
-                                       start = nextf;
-                               else
-                               {
-                                       printk(KERN_WARNING"isdn_mppp(seq %d):"
-                                               " END flag with no following "
-                                               "BEGIN", thisseq);
+                                       start = nextf;
+                               else {
+                                       printk(KERN_WARNING"isdn_mppp(seq %d):"
+                                              " END flag with no following "
+                                              "BEGIN", thisseq);
                                        stats->seqerrs++;
                                }
                        }
-
-               } else {
-                       if ( nextf != NULL && frag != NULL &&
-                                               MP_LT(thisseq, minseq)) {
+               } else {
+                       if (nextf != (struct sk_buff *)&mp->frags &&
+                           frag != NULL &&
+                           MP_LT(thisseq, minseq)) {
                                /* we've got a break in the sequence
                                 * and we not at the end yet
                                 * and we did not just reassembled
@@ -1782,41 +1767,39 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp,
                                 * discard all the frames below low watermark 
                                 * and start over */
                                stats->frame_drops++;
-                               mp->frags = isdn_ppp_mp_discard(mp,start,nextf);
+                               isdn_ppp_mp_discard(mp, start, nextf);
                        }
                        /* break in the sequence, no reassembly */
-                       start = NULL;
-               }
-                               
-               frag = nextf;
-       }       /* while -- main loop */
-       
-       if (mp->frags == NULL)
-               mp->frags = frag;
-               
+                       start = NULL;
+               }
+               if (!start)
+                       break;
+       }
+
+check_overflow:
        /* rather straighforward way to deal with (not very) possible 
-        * queue overflow */
+        * queue overflow
+        */
        if (mp->frames > MP_MAX_QUEUE_LEN) {
                stats->overflows++;
-               while (mp->frames > MP_MAX_QUEUE_LEN) {
-                       frag = mp->frags->next;
-                       isdn_ppp_mp_free_skb(mp, mp->frags);
-                       mp->frags = frag;
+               skb_queue_walk_safe(&mp->frags, frag, nextf) {
+                       if (mp->frames <= MP_MAX_QUEUE_LEN)
+                               break;
+                       __skb_unlink(frag, &mp->frags);
+                       isdn_ppp_mp_free_skb(mp, frag);
                }
        }
        spin_unlock_irqrestore(&mp->lock, flags);
 }
 
-static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
+static void isdn_ppp_mp_cleanup(isdn_net_local *lp)
 {
-       struct sk_buff * frag = lp->netdev->pb->frags;
-       struct sk_buff * nextfrag;
-       while( frag ) {
-               nextfrag = frag->next;
-               isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
-               frag = nextfrag;
-       }
-       lp->netdev->pb->frags = NULL;
+       struct sk_buff *skb, *tmp;
+
+       skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) {
+               __skb_unlink(skb, &lp->netdev->pb->frags);
+               isdn_ppp_mp_free_skb(lp->netdev->pb, skb);
+       }
 }
 
 static u32 isdn_ppp_mp_get_seq( int short_seq, 
@@ -1853,72 +1836,115 @@ static u32 isdn_ppp_mp_get_seq( int short_seq,
        return seq;
 }
 
-struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
-                       struct sk_buff * from, struct sk_buff * to )
+static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from,
+                               struct sk_buff *to)
 {
-       if( from )
-               while (from != to) {
-                       struct sk_buff * next = from->next;
-                       isdn_ppp_mp_free_skb(mp, from);
-                       from = next;
+       if (from) {
+               struct sk_buff *skb, *tmp;
+               int freeing = 0;
+
+               skb_queue_walk_safe(&mp->frags, skb, tmp) {
+                       if (skb == to)
+                               break;
+                       if (skb == from)
+                               freeing = 1;
+                       if (!freeing)
+                               continue;
+                       __skb_unlink(skb, &mp->frags);
+                       isdn_ppp_mp_free_skb(mp, skb);
                }
-       return from;
+       }
 }
 
-void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
-                               struct sk_buff * from, struct sk_buff * to )
+static unsigned int calc_tot_len(struct sk_buff_head *queue,
+                                struct sk_buff *from, struct sk_buff *to)
 {
-       ippp_bundle * mp = net_dev->pb;
-       int proto;
-       struct sk_buff * skb;
+       unsigned int tot_len = 0;
+       struct sk_buff *skb;
+       int found_start = 0;
+
+       skb_queue_walk(queue, skb) {
+               if (skb == from)
+                       found_start = 1;
+               if (!found_start)
+                       continue;
+               tot_len += skb->len - MP_HEADER_LEN;
+               if (skb == to)
+                       break;
+       }
+       return tot_len;
+}
+
+/* Reassemble packet using fragments in the reassembly queue from
+ * 'from' until 'to', inclusive.
+ */
+static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
+                                  struct sk_buff *from, struct sk_buff *to,
+                                  u32 lastseq)
+{
+       ippp_bundle *mp = net_dev->pb;
        unsigned int tot_len;
+       struct sk_buff *skb;
+       int proto;
 
        if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
                printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
                        __func__, lp->ppp_slot);
                return;
        }
-       if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
-               if( ippp_table[lp->ppp_slot]->debug & 0x40 )
+
+       tot_len = calc_tot_len(&mp->frags, from, to);
+
+       if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) {
+               if (ippp_table[lp->ppp_slot]->debug & 0x40)
                        printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
-                                       "len %d\n", MP_SEQ(from), from->len );
+                              "len %d\n", MP_SEQ(from), from->len);
                skb = from;
                skb_pull(skb, MP_HEADER_LEN);
+               __skb_unlink(skb, &mp->frags);
                mp->frames--;   
        } else {
-               struct sk_buff * frag;
-               int n;
+               struct sk_buff *walk, *tmp;
+               int found_start = 0;
 
-               for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++)
-                       tot_len += frag->len - MP_HEADER_LEN;
-
-               if( ippp_table[lp->ppp_slot]->debug & 0x40 )
+               if (ippp_table[lp->ppp_slot]->debug & 0x40)
                        printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
-                               "to %d, len %d\n", MP_SEQ(from), 
-                               (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len );
-               if( (skb = dev_alloc_skb(tot_len)) == NULL ) {
+                              "to %d, len %d\n", MP_SEQ(from), lastseq,
+                              tot_len);
+
+               skb = dev_alloc_skb(tot_len);
+               if (!skb)
                        printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
-                                       "of size %d\n", tot_len);
-                       isdn_ppp_mp_discard(mp, from, to);
-                       return;
-               }
+                              "of size %d\n", tot_len);
+
+               found_start = 0;
+               skb_queue_walk_safe(&mp->frags, walk, tmp) {
+                       if (walk == from)
+                               found_start = 1;
+                       if (!found_start)
+                               continue;
 
-               while( from != to ) {
-                       unsigned int len = from->len - MP_HEADER_LEN;
+                       if (skb) {
+                               unsigned int len = walk->len - MP_HEADER_LEN;
+                               skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN,
+                                                                skb_put(skb, len),
+                                                                len);
+                       }
+                       __skb_unlink(walk, &mp->frags);
+                       isdn_ppp_mp_free_skb(mp, walk);
 
-                       skb_copy_from_linear_data_offset(from, MP_HEADER_LEN,
-                                                        skb_put(skb,len),
-                                                        len);
-                       frag = from->next;
-                       isdn_ppp_mp_free_skb(mp, from);
-                       from = frag; 
+                       if (walk == to)
+                               break;
                }
        }
+       if (!skb)
+               return;
+
        proto = isdn_ppp_strip_proto(skb);
        isdn_ppp_push_higher(net_dev, lp, skb, proto);
 }
 
-static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
+static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb)
 {
        dev_kfree_skb(skb);
        mp->frames--;
index b5fabc7019d88f54b26d494ae296803d43c9c5fd..e7462924b5050fb70cad3ddfd9f607368d61e774 100644 (file)
@@ -124,18 +124,6 @@ mISDN_read(struct file *filep, char *buf, size_t count, loff_t *off)
        return ret;
 }
 
-static loff_t
-mISDN_llseek(struct file *filep, loff_t offset, int orig)
-{
-       return -ESPIPE;
-}
-
-static ssize_t
-mISDN_write(struct file *filep, const char *buf, size_t count, loff_t *off)
-{
-       return -EOPNOTSUPP;
-}
-
 static unsigned int
 mISDN_poll(struct file *filep, poll_table *wait)
 {
@@ -157,8 +145,9 @@ mISDN_poll(struct file *filep, poll_table *wait)
 }
 
 static void
-dev_expire_timer(struct mISDNtimer *timer)
+dev_expire_timer(unsigned long data)
 {
+       struct mISDNtimer *timer = (void *)data;
        u_long                  flags;
 
        spin_lock_irqsave(&timer->dev->lock, flags);
@@ -191,7 +180,7 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout)
                spin_unlock_irqrestore(&dev->lock, flags);
                timer->dev = dev;
                timer->tl.data = (long)timer;
-               timer->tl.function = (void *) dev_expire_timer;
+               timer->tl.function = dev_expire_timer;
                init_timer(&timer->tl);
                timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000);
                add_timer(&timer->tl);
@@ -211,6 +200,9 @@ misdn_del_timer(struct mISDNtimerdev *dev, int id)
        list_for_each_entry(timer, &dev->pending, list) {
                if (timer->id == id) {
                        list_del_init(&timer->list);
+                       /* RED-PEN AK: race -- timer can be still running on
+                        * other CPU. Needs reference count I think
+                        */
                        del_timer(&timer->tl);
                        ret = timer->id;
                        kfree(timer);
@@ -268,9 +260,7 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
 }
 
 static struct file_operations mISDN_fops = {
-       .llseek         = mISDN_llseek,
        .read           = mISDN_read,
-       .write          = mISDN_write,
        .poll           = mISDN_poll,
        .ioctl          = mISDN_ioctl,
        .open           = mISDN_open,
index 4790c83d78d0cd52adbfb4d4c394eb9d7ec4c691..deeac4b44173d959b2fca6ca7f9abf57aa419f55 100644 (file)
@@ -5761,7 +5761,11 @@ void md_do_sync(mddev_t *mddev)
                                         * time 'round when curr_resync == 2
                                         */
                                        continue;
-                               prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE);
+                               /* We need to wait 'interruptible' so as not to
+                                * contribute to the load average, and not to
+                                * be caught by 'softlockup'
+                                */
+                               prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE);
                                if (!kthread_should_stop() &&
                                    mddev2->curr_resync >= mddev->curr_resync) {
                                        printk(KERN_INFO "md: delaying %s of %s"
@@ -5769,6 +5773,8 @@ void md_do_sync(mddev_t *mddev)
                                               " share one or more physical units)\n",
                                               desc, mdname(mddev), mdname(mddev2));
                                        mddev_put(mddev2);
+                                       if (signal_pending(current))
+                                               flush_signals(current);
                                        schedule();
                                        finish_wait(&resync_wait, &wq);
                                        goto try_again;
index ecbfa1b39b701034c6c6da823b409527b5bd4ab0..3e9e0dcd217ecfaf278cdef11f6cb8cb18f666a2 100644 (file)
@@ -968,7 +968,7 @@ config VIDEO_PXA27x
 
 config VIDEO_SH_MOBILE_CEU
        tristate "SuperH Mobile CEU Interface driver"
-       depends on VIDEO_DEV
+       depends on VIDEO_DEV && HAS_DMA
        select SOC_CAMERA
        select VIDEOBUF_DMA_CONTIG
        ---help---
index a38005008a2019c7beb7f1ae32193d488438bf78..cea46906408ecbc090aa988b51d7abe1fbf1b666 100644 (file)
@@ -185,7 +185,7 @@ static void memstick_free(struct device *dev)
 }
 
 static struct class memstick_host_class = {
-       .name       = "memstick_host",
+       .name        = "memstick_host",
        .dev_release = memstick_free
 };
 
@@ -264,7 +264,7 @@ EXPORT_SYMBOL(memstick_new_req);
  * @sg - TPC argument
  */
 void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
-                         struct scatterlist *sg)
+                         const struct scatterlist *sg)
 {
        mrq->tpc = tpc;
        if (tpc & 8)
@@ -294,7 +294,7 @@ EXPORT_SYMBOL(memstick_init_req_sg);
  * user supplied buffer.
  */
 void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
-                      void *buf, size_t length)
+                      const void *buf, size_t length)
 {
        mrq->tpc = tpc;
        if (tpc & 8)
@@ -439,7 +439,7 @@ static void memstick_check(struct work_struct *work)
        if (!host->card) {
                if (memstick_power_on(host))
                        goto out_power_off;
-       } else
+       } else if (host->card->stop)
                host->card->stop(host->card);
 
        card = memstick_alloc_card(host);
@@ -458,7 +458,7 @@ static void memstick_check(struct work_struct *work)
                            || !(host->card->check(host->card))) {
                                device_unregister(&host->card->dev);
                                host->card = NULL;
-                       } else
+                       } else if (host->card->start)
                                host->card->start(host->card);
                }
 
index 44b1817f2f2f02116d2f78a9d16b19c623f93d7c..d2d2318dafa4af7fd8ab885528f693bd886e5e54 100644 (file)
@@ -30,6 +30,8 @@ module_param(major, int, 0644);
 #define MSPRO_BLOCK_SIGNATURE        0xa5c3
 #define MSPRO_BLOCK_MAX_ATTRIBUTES   41
 
+#define MSPRO_BLOCK_PART_SHIFT 3
+
 enum {
        MSPRO_BLOCK_ID_SYSINFO         = 0x10,
        MSPRO_BLOCK_ID_MODELNAME       = 0x15,
@@ -195,7 +197,7 @@ static int mspro_block_bd_open(struct inode *inode, struct file *filp)
 static int mspro_block_disk_release(struct gendisk *disk)
 {
        struct mspro_block_data *msb = disk->private_data;
-       int disk_id = disk->first_minor >> MEMSTICK_PART_SHIFT;
+       int disk_id = disk->first_minor >> MSPRO_BLOCK_PART_SHIFT;
 
        mutex_lock(&mspro_block_disk_lock);
 
@@ -877,6 +879,7 @@ static int mspro_block_switch_interface(struct memstick_dev *card)
        struct mspro_block_data *msb = memstick_get_drvdata(card);
        int rc = 0;
 
+try_again:
        if (msb->caps & MEMSTICK_CAP_PAR4)
                rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR4);
        else
@@ -930,6 +933,18 @@ static int mspro_block_switch_interface(struct memstick_dev *card)
                rc = memstick_set_rw_addr(card);
                if (!rc)
                        rc = mspro_block_set_interface(card, msb->system);
+
+               if (!rc) {
+                       msleep(150);
+                       rc = mspro_block_wait_for_ced(card);
+                       if (rc)
+                               return rc;
+
+                       if (msb->caps & MEMSTICK_CAP_PAR8) {
+                               msb->caps &= ~MEMSTICK_CAP_PAR8;
+                               goto try_again;
+                       }
+               }
        }
        return rc;
 }
@@ -1117,14 +1132,16 @@ static int mspro_block_init_card(struct memstick_dev *card)
                return -EIO;
 
        msb->caps = host->caps;
-       rc = mspro_block_switch_interface(card);
+
+       msleep(150);
+       rc = mspro_block_wait_for_ced(card);
        if (rc)
                return rc;
 
-       msleep(200);
-       rc = mspro_block_wait_for_ced(card);
+       rc = mspro_block_switch_interface(card);
        if (rc)
                return rc;
+
        dev_dbg(&card->dev, "card activated\n");
        if (msb->system != MEMSTICK_SYS_SERIAL)
                msb->caps |= MEMSTICK_CAP_AUTO_GET_INT;
@@ -1192,12 +1209,12 @@ static int mspro_block_init_disk(struct memstick_dev *card)
        if (rc)
                return rc;
 
-       if ((disk_id << MEMSTICK_PART_SHIFT) > 255) {
+       if ((disk_id << MSPRO_BLOCK_PART_SHIFT) > 255) {
                rc = -ENOSPC;
                goto out_release_id;
        }
 
-       msb->disk = alloc_disk(1 << MEMSTICK_PART_SHIFT);
+       msb->disk = alloc_disk(1 << MSPRO_BLOCK_PART_SHIFT);
        if (!msb->disk) {
                rc = -ENOMEM;
                goto out_release_id;
@@ -1220,7 +1237,7 @@ static int mspro_block_init_disk(struct memstick_dev *card)
                                   MSPRO_BLOCK_MAX_PAGES * msb->page_size);
 
        msb->disk->major = major;
-       msb->disk->first_minor = disk_id << MEMSTICK_PART_SHIFT;
+       msb->disk->first_minor = disk_id << MSPRO_BLOCK_PART_SHIFT;
        msb->disk->fops = &ms_block_bdops;
        msb->usage_count = 1;
        msb->disk->private_data = msb;
@@ -1416,7 +1433,7 @@ out_unlock:
 
 static struct memstick_device_id mspro_block_id_tbl[] = {
        {MEMSTICK_MATCH_ALL, MEMSTICK_TYPE_PRO, MEMSTICK_CATEGORY_STORAGE_DUO,
-        MEMSTICK_CLASS_GENERIC_DUO},
+        MEMSTICK_CLASS_DUO},
        {}
 };
 
index 3485c63d20b04c0793be29f07d4fffd38f9de457..2fb95a5b72eb2ede1c55c295ab946c3b2cede474 100644 (file)
@@ -81,6 +81,8 @@ struct jmb38x_ms {
 #define TPC_CODE_SZ_MASK       0x00000700
 #define TPC_DATA_SZ_MASK       0x00000007
 
+#define HOST_CONTROL_TDELAY_EN 0x00040000
+#define HOST_CONTROL_HW_OC_P   0x00010000
 #define HOST_CONTROL_RESET_REQ 0x00008000
 #define HOST_CONTROL_REI       0x00004000
 #define HOST_CONTROL_LED       0x00000400
@@ -88,6 +90,7 @@ struct jmb38x_ms {
 #define HOST_CONTROL_RESET     0x00000100
 #define HOST_CONTROL_POWER_EN  0x00000080
 #define HOST_CONTROL_CLOCK_EN  0x00000040
+#define HOST_CONTROL_REO       0x00000008
 #define HOST_CONTROL_IF_SHIFT  4
 
 #define HOST_CONTROL_IF_SERIAL 0x0
@@ -133,11 +136,15 @@ struct jmb38x_ms {
 #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
 
 #define CLOCK_CONTROL_40MHZ   0x00000001
-#define CLOCK_CONTROL_50MHZ   0x00000002
+#define CLOCK_CONTROL_50MHZ   0x0000000a
 #define CLOCK_CONTROL_60MHZ   0x00000008
 #define CLOCK_CONTROL_62_5MHZ 0x0000000c
 #define CLOCK_CONTROL_OFF     0x00000000
 
+#define PCI_CTL_CLOCK_DLY_ADDR   0x000000b0
+#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00
+#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000
+
 enum {
        CMD_READY    = 0x01,
        FIFO_READY   = 0x02,
@@ -367,8 +374,7 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh)
                return host->req->error;
        }
 
-       dev_dbg(&msh->dev, "control %08x\n",
-               readl(host->addr + HOST_CONTROL));
+       dev_dbg(&msh->dev, "control %08x\n", readl(host->addr + HOST_CONTROL));
        dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS));
        dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS));
 
@@ -637,7 +643,7 @@ static int jmb38x_ms_reset(struct jmb38x_ms_host *host)
                ndelay(20);
        }
        dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n");
-       return -EIO;
+       /* return -EIO; */
 
 reset_next:
        writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN
@@ -680,7 +686,9 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
 
                        host_ctl = 7;
                        host_ctl |= HOST_CONTROL_POWER_EN
-                                | HOST_CONTROL_CLOCK_EN;
+                                   | HOST_CONTROL_CLOCK_EN
+                                   | HOST_CONTROL_HW_OC_P
+                                   | HOST_CONTROL_TDELAY_EN;
                        writel(host_ctl, host->addr + HOST_CONTROL);
 
                        writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
@@ -704,33 +712,40 @@ static int jmb38x_ms_set_param(struct memstick_host *msh,
                break;
        case MEMSTICK_INTERFACE:
                host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);
+               pci_read_config_dword(host->chip->pdev,
+                                     PCI_CTL_CLOCK_DLY_ADDR,
+                                     &clock_delay);
+               clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B
+                                       : ~PCI_CTL_CLOCK_DLY_MASK_A;
 
                if (value == MEMSTICK_SERIAL) {
                        host_ctl &= ~HOST_CONTROL_FAST_CLK;
+                       host_ctl &= ~HOST_CONTROL_REO;
                        host_ctl |= HOST_CONTROL_IF_SERIAL
                                    << HOST_CONTROL_IF_SHIFT;
                        host_ctl |= HOST_CONTROL_REI;
                        clock_ctl = CLOCK_CONTROL_40MHZ;
-                       clock_delay = 0;
                } else if (value == MEMSTICK_PAR4) {
-                       host_ctl |= HOST_CONTROL_FAST_CLK;
+                       host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO;
                        host_ctl |= HOST_CONTROL_IF_PAR4
                                    << HOST_CONTROL_IF_SHIFT;
                        host_ctl &= ~HOST_CONTROL_REI;
                        clock_ctl = CLOCK_CONTROL_40MHZ;
-                       clock_delay = 4;
+                       clock_delay |= host->id ? (4 << 12) : (4 << 8);
                } else if (value == MEMSTICK_PAR8) {
                        host_ctl |= HOST_CONTROL_FAST_CLK;
                        host_ctl |= HOST_CONTROL_IF_PAR8
                                    << HOST_CONTROL_IF_SHIFT;
-                       host_ctl &= ~HOST_CONTROL_REI;
-                       clock_ctl = CLOCK_CONTROL_60MHZ;
-                       clock_delay = 0;
+                       host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO);
+                       clock_ctl = CLOCK_CONTROL_50MHZ;
                } else
                        return -EINVAL;
+
                writel(host_ctl, host->addr + HOST_CONTROL);
                writel(clock_ctl, host->addr + CLOCK_CONTROL);
-               writel(clock_delay, host->addr + CLOCK_DELAY);
+               pci_write_config_dword(host->chip->pdev,
+                                      PCI_CTL_CLOCK_DLY_ADDR,
+                                      clock_delay);
                break;
        };
        return 0;
index 23c91f5f6b61c5425d1653390fdca05c1378db03..d61cee796efdc234aba44fdcb5969283f24780d7 100644 (file)
@@ -445,6 +445,9 @@ static void __exit gru_exit(void)
        int order = get_order(sizeof(struct gru_state) *
                              GRU_CHIPLETS_PER_BLADE);
 
+       if (!IS_UV())
+               return;
+
        for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
                free_irq(IRQ_GRU + i, NULL);
 
index 6986f392624426e0bfa6cb0f6085766f56cae90e..ebc8b9d77613132f290b7372196ab50bfe416144 100644 (file)
@@ -615,14 +615,19 @@ static struct mmc_driver mmc_driver = {
 
 static int __init mmc_blk_init(void)
 {
-       int res = -ENOMEM;
+       int res;
 
        res = register_blkdev(MMC_BLOCK_MAJOR, "mmc");
        if (res)
                goto out;
 
-       return mmc_register_driver(&mmc_driver);
+       res = mmc_register_driver(&mmc_driver);
+       if (res)
+               goto out2;
 
+       return 0;
+ out2:
+       unregister_blkdev(MMC_BLOCK_MAJOR, "mmc");
  out:
        return res;
 }
index f26b01d811ae9f51560dbb2c3db9418e1a8672b5..b92b172074ee5a6f2b698a0292951b900dbd3008 100644 (file)
@@ -1040,7 +1040,7 @@ static const struct mmc_test_case mmc_test_cases[] = {
 
 };
 
-static struct mutex mmc_test_lock;
+static DEFINE_MUTEX(mmc_test_lock);
 
 static void mmc_test_run(struct mmc_test_card *test, int testcase)
 {
@@ -1171,8 +1171,6 @@ static int mmc_test_probe(struct mmc_card *card)
        if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD))
                return -ENODEV;
 
-       mutex_init(&mmc_test_lock);
-
        ret = device_create_file(&card->dev, &dev_attr_test);
        if (ret)
                return ret;
index 0bd06f5bd62ffa414439dcd3a4c382124832c779..917035e16da4c10eb53745fc07b5b62e20738d64 100644 (file)
@@ -195,7 +195,9 @@ static int atmci_regs_show(struct seq_file *s, void *v)
 
        /* Grab a more or less consistent snapshot */
        spin_lock_irq(&host->mmc->lock);
+       clk_enable(host->mck);
        memcpy_fromio(buf, host->regs, MCI_REGS_SIZE);
+       clk_disable(host->mck);
        spin_unlock_irq(&host->mmc->lock);
 
        seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n",
@@ -216,6 +218,8 @@ static int atmci_regs_show(struct seq_file *s, void *v)
        atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]);
        atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]);
 
+       kfree(buf);
+
        return 0;
 }
 
@@ -237,7 +241,6 @@ static void atmci_init_debugfs(struct atmel_mci *host)
        struct mmc_host *mmc;
        struct dentry   *root;
        struct dentry   *node;
-       struct resource *res;
 
        mmc = host->mmc;
        root = mmc->debugfs_root;
@@ -251,9 +254,6 @@ static void atmci_init_debugfs(struct atmel_mci *host)
        if (!node)
                goto err;
 
-       res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
-       node->d_inode->i_size = res->end - res->start + 1;
-
        node = debugfs_create_file("req", S_IRUSR, root, host, &atmci_req_fops);
        if (!node)
                goto err;
@@ -1059,6 +1059,10 @@ static int __init atmci_probe(struct platform_device *pdev)
                        host->present = !gpio_get_value(host->detect_pin);
                }
        }
+
+       if (!gpio_is_valid(host->detect_pin))
+               mmc->caps |= MMC_CAP_NEEDS_POLL;
+
        if (gpio_is_valid(host->wp_pin)) {
                if (gpio_request(host->wp_pin, "mmc_wp")) {
                        dev_dbg(&mmc->class_dev, "no WP pin available\n");
index 9e647a06054f886f8df4b51ed4af26824b6af8a6..ba2b4240a86ad722c82a3e910d8cbb129305664b 100644 (file)
@@ -159,10 +159,10 @@ static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host,
 #define STATUS_TO_TEXT(a) \
        do { \
                if (status & TMIO_STAT_##a) \
-                       printf(#a); \
+                       printk(#a); \
        } while (0)
 
-void debug_status(u32 status)
+void pr_debug_status(u32 status)
 {
        printk(KERN_DEBUG "status: %08x = ", status);
        STATUS_TO_TEXT(CARD_REMOVE);
index fdfb2b2cb734e3fe31455a34dcb7e8eaef495749..a424869707a5225b1f04e9d2e070a87d1987f19a 100644 (file)
@@ -130,12 +130,12 @@ static const char filename[] = __FILE__;
 
 static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
 #define TIMEOUT_MSG(lineno) \
-       printk(timeout_msg, filename,__FUNCTION__,(lineno))
+       printk(timeout_msg, filename,__func__,(lineno))
 
 static const char invalid_pcb_msg[] =
 "*** invalid pcb length %d at %s:%s (line %d) ***\n";
 #define INVALID_PCB_MSG(len) \
-       printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__)
+       printk(invalid_pcb_msg, (len),filename,__func__,__LINE__)
 
 static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x...";
 
index f6ca99774cc21405f88c5ce72659f3c0af1d9429..32e66f0d4344391f9eeb3015939eec93c4d79aaa 100644 (file)
@@ -309,7 +309,7 @@ enum RTL8139_registers {
        Cfg9346         = 0x50,
        Config0         = 0x51,
        Config1         = 0x52,
-       FlashReg        = 0x54,
+       TimerInt        = 0x54,
        MediaStatus     = 0x58,
        Config3         = 0x59,
        Config4         = 0x5A,  /* absent on RTL-8139A */
@@ -325,6 +325,7 @@ enum RTL8139_registers {
        FIFOTMS         = 0x70,  /* FIFO Control and test. */
        CSCR            = 0x74,  /* Chip Status and Configuration Register. */
        PARA78          = 0x78,
+       FlashReg        = 0xD4, /* Communication with Flash ROM, four bytes. */
        PARA7c          = 0x7c,  /* Magic transceiver parameter register. */
        Config5         = 0xD8,  /* absent on RTL-8139A */
 };
index 69c81da48ebc7fcb8f683a5733208a4d40f8b993..2d6a060d92e5aeb733ca0280a45fc10f5c5cc188 100644 (file)
@@ -1813,7 +1813,7 @@ config FEC2
 
 config FEC_MPC52xx
        tristate "MPC52xx FEC driver"
-       depends on PPC_MERGE && PPC_MPC52xx && PPC_BESTCOMM_FEC
+       depends on PPC_MPC52xx && PPC_BESTCOMM_FEC
        select CRC32
        select PHYLIB
        ---help---
@@ -1938,15 +1938,6 @@ config E1000
          To compile this driver as a module, choose M here. The module
          will be called e1000.
 
-config E1000_DISABLE_PACKET_SPLIT
-       bool "Disable Packet Split for PCI express adapters"
-       depends on E1000
-       help
-         Say Y here if you want to use the legacy receive path for PCI express
-         hardware.
-
-         If in doubt, say N.
-
 config E1000E
        tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
        depends on PCI && (!SPARC32 || BROKEN)
@@ -2057,6 +2048,7 @@ config R8169
        tristate "Realtek 8169 gigabit ethernet support"
        depends on PCI
        select CRC32
+       select MII
        ---help---
          Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
 
@@ -2273,7 +2265,7 @@ config UGETH_TX_ON_DEMAND
 config MV643XX_ETH
        tristate "Marvell Discovery (643XX) and Orion ethernet support"
        depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
-       select MII
+       select PHYLIB
        help
          This driver supports the gigabit ethernet MACs in the
          Marvell Discovery PPC/MIPS chipset family (MV643XX) and
@@ -2411,6 +2403,7 @@ config IXGBE
        tristate "Intel(R) 10GbE PCI Express adapters support"
        depends on PCI && INET
        select INET_LRO
+       select INTEL_IOATDMA
        ---help---
          This driver supports Intel(R) 10GbE PCI Express family of
          adapters.  For more information on how to identify your adapter, go
@@ -2462,6 +2455,7 @@ config MYRI10GE
        select FW_LOADER
        select CRC32
        select INET_LRO
+       select INTEL_IOATDMA
        ---help---
          This driver supports Myricom Myri-10G Dual Protocol interface in
          Ethernet mode. If the eeprom on your board is not recent enough,
index bdc4c0bb56d90965bec6b1b265bb98bf9521c768..a5b07691e466d6cc43b210796144eece8947d15c 100644 (file)
@@ -442,24 +442,24 @@ static int arcnet_open(struct net_device *dev)
                BUGMSG(D_NORMAL, "WARNING!  Station address FF may confuse "
                       "DOS networking programs!\n");
 
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
        if (ASTATUS() & RESETflag) {
-               BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+               BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
                ACOMMAND(CFLAGScmd | RESETclear);
        }
 
 
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
        /* make sure we're ready to receive IRQ's. */
        AINTMASK(0);
        udelay(1);              /* give it time to set the mask before
                                 * we reset it again. (may not even be
                                 * necessary)
                                 */
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
        lp->intmask = NORXflag | RECONflag;
        AINTMASK(lp->intmask);
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
 
        netif_start_queue(dev);
 
@@ -670,14 +670,14 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
                freeskb = 0;
        }
 
-       BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
+       BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
        /* make sure we didn't ignore a TX IRQ while we were in here */
        AINTMASK(0);
 
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
        lp->intmask |= TXFREEflag|EXCNAKflag;
        AINTMASK(lp->intmask);
-       BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
+       BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS());
 
        spin_unlock_irqrestore(&lp->lock, flags);
        if (freeskb) {
@@ -798,7 +798,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
                 diagstatus = (status >> 8) & 0xFF;
 
                BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n",
-                       __FILE__,__LINE__,__FUNCTION__,status);
+                       __FILE__,__LINE__,__func__,status);
                didsomething = 0;
 
                /*
index 8b51313b1300b9f5b4c30c2eb9ff3383c2cb759f..70124a944e7d61f59b89fdb7544339278d7d3f40 100644 (file)
@@ -238,15 +238,15 @@ static int com20020_reset(struct net_device *dev, int really_reset)
        u_char inbyte;
 
        BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
-               __FILE__,__LINE__,__FUNCTION__,dev,lp,dev->name);
+               __FILE__,__LINE__,__func__,dev,lp,dev->name);
        BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n",
               dev->name, ASTATUS());
 
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
        lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
        /* power-up defaults */
        SETCONF;
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
 
        if (really_reset) {
                /* reset the card */
@@ -254,22 +254,22 @@ static int com20020_reset(struct net_device *dev, int really_reset)
                mdelay(RESETtime * 2);  /* COM20020 seems to be slower sometimes */
        }
        /* clear flags & end reset */
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
        ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
 
        /* verify that the ARCnet signature byte is present */
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
 
        com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
        if (inbyte != TESTvalue) {
-               BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+               BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
                BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
                return 1;
        }
        /* enable extended (512-byte) packets */
        ACOMMAND(CONFIGcmd | EXTconf);
-       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__);
+       BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__);
 
        /* done!  return success. */
        return 0;
index 949e75358bf098cffd84355aa6688d9ce3aecbd4..8cbc1b59bd6287303c6fe179eb5af6084cad5de7 100644 (file)
@@ -397,7 +397,7 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw)
  */
 int atl1e_phy_commit(struct atl1e_hw *hw)
 {
-       struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
+       struct atl1e_adapter *adapter = hw->adapter;
        struct pci_dev *pdev = adapter->pdev;
        int ret_val;
        u16 phy_data;
@@ -431,7 +431,7 @@ int atl1e_phy_commit(struct atl1e_hw *hw)
 
 int atl1e_phy_init(struct atl1e_hw *hw)
 {
-       struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
+       struct atl1e_adapter *adapter = hw->adapter;
        struct pci_dev *pdev = adapter->pdev;
        s32 ret_val;
        u16 phy_val;
@@ -525,7 +525,7 @@ int atl1e_phy_init(struct atl1e_hw *hw)
  */
 int atl1e_reset_hw(struct atl1e_hw *hw)
 {
-       struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter;
+       struct atl1e_adapter *adapter = hw->adapter;
        struct pci_dev *pdev = adapter->pdev;
 
        u32 idle_status_data = 0;
index 7685b995ff9b5d0ad20ab8bf2bc3ae7f8a1510f0..9b603528143d6dcee4da35059d74a7a0e8902964 100644 (file)
@@ -2390,9 +2390,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev,
        }
 
        /* Init GPHY as early as possible due to power saving issue  */
-       spin_lock(&adapter->mdio_lock);
        atl1e_phy_init(&adapter->hw);
-       spin_unlock(&adapter->mdio_lock);
        /* reset the controller to
         * put the device in a known good starting state */
        err = atl1e_reset_hw(&adapter->hw);
index d548a67da1e881501f243e2335b18367b028cc27..5ab9c76310023856c59b0e983e84d1afe9dbe3c4 100644 (file)
@@ -522,8 +522,10 @@ static void atl2_intr_tx(struct atl2_adapter *adapter)
                atomic_set(&adapter->txd_read_ptr, (int)txd_read_ptr);
 
                /* tx statistics: */
-               if (txs->ok)
+               if (txs->ok) {
+                       adapter->net_stats.tx_bytes += txs->pkt_size;
                        adapter->net_stats.tx_packets++;
+               }
                else
                        adapter->net_stats.tx_errors++;
 
index 5ee1b0557a028f1bf7c6e621c50a60d0a6c14e9f..92c16c37ff232a3b87a5228cac4d76f6213998ef 100644 (file)
@@ -653,6 +653,8 @@ static struct net_device * au1000_probe(int port_num)
 
        aup = dev->priv;
 
+       spin_lock_init(&aup->lock);
+
        /* Allocate the data buffers */
        /* Snooping works fine with eth on all au1xxx */
        aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE *
@@ -753,7 +755,6 @@ static struct net_device * au1000_probe(int port_num)
                aup->tx_db_inuse[i] = pDB;
        }
 
-       spin_lock_init(&aup->lock);
        dev->base_addr = base;
        dev->irq = irq;
        dev->open = au1000_open;
index a886a4b9f7e5e24b97f7efe6f3e3aba559221cf9..4207d6efddc097c5b62df3db15d726e102f612e1 100644 (file)
@@ -153,7 +153,7 @@ static void ax_reset_8390(struct net_device *dev)
        while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
                if (jiffies - reset_start_time > 2*HZ/100) {
                        dev_warn(&ax->dev->dev, "%s: %s did not complete.\n",
-                              __FUNCTION__, dev->name);
+                              __func__, dev->name);
                        break;
                }
        }
@@ -173,7 +173,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
        if (ei_status.dmaing) {
                dev_err(&ax->dev->dev, "%s: DMAing conflict in %s "
                        "[DMAstat:%d][irqlock:%d].\n",
-                       dev->name, __FUNCTION__,
+                       dev->name, __func__,
                        ei_status.dmaing, ei_status.irqlock);
                return;
        }
@@ -215,7 +215,7 @@ static void ax_block_input(struct net_device *dev, int count,
                dev_err(&ax->dev->dev,
                        "%s: DMAing conflict in %s "
                        "[DMAstat:%d][irqlock:%d].\n",
-                       dev->name, __FUNCTION__,
+                       dev->name, __func__,
                        ei_status.dmaing, ei_status.irqlock);
                return;
        }
@@ -260,7 +260,7 @@ static void ax_block_output(struct net_device *dev, int count,
        if (ei_status.dmaing) {
                dev_err(&ax->dev->dev, "%s: DMAing conflict in %s."
                        "[DMAstat:%d][irqlock:%d]\n",
-                       dev->name, __FUNCTION__,
+                       dev->name, __func__,
                       ei_status.dmaing, ei_status.irqlock);
                return;
        }
@@ -396,7 +396,7 @@ ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
 {
        if (phy_debug)
                pr_debug("%s: dev %p, %04x, %04x, %d\n",
-                       __FUNCTION__, dev, phy_addr, reg, opc);
+                       __func__, dev, phy_addr, reg, opc);
 
        ax_mii_ei_outbits(dev, 0x3f, 6);        /* pre-amble */
        ax_mii_ei_outbits(dev, 1, 2);           /* frame-start */
@@ -422,7 +422,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg)
        spin_unlock_irqrestore(&ei_local->page_lock, flags);
 
        if (phy_debug)
-               pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
+               pr_debug("%s: %04x.%04x => read %04x\n", __func__,
                         phy_addr, reg, result);
 
        return result;
@@ -436,7 +436,7 @@ ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
        unsigned long flags;
 
        dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n",
-               __FUNCTION__, dev, phy_addr, reg, value);
+               __func__, dev, phy_addr, reg, value);
 
        spin_lock_irqsave(&ei->page_lock, flags);
 
index 3db7db1828e789920ad9108a425918c493c08c38..df896e23e2c59171921bca1b767ee37580d4e619 100644 (file)
@@ -811,7 +811,7 @@ static void bfin_mac_enable(void)
 {
        u32 opmode;
 
-       pr_debug("%s: %s\n", DRV_NAME, __FUNCTION__);
+       pr_debug("%s: %s\n", DRV_NAME, __func__);
 
        /* Set RX DMA */
        bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a));
@@ -847,7 +847,7 @@ static void bfin_mac_enable(void)
 /* Our watchdog timed out. Called by the networking layer */
 static void bfin_mac_timeout(struct net_device *dev)
 {
-       pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+       pr_debug("%s: %s\n", dev->name, __func__);
 
        bfin_mac_disable();
 
@@ -949,7 +949,7 @@ static int bfin_mac_open(struct net_device *dev)
 {
        struct bfin_mac_local *lp = netdev_priv(dev);
        int retval;
-       pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+       pr_debug("%s: %s\n", dev->name, __func__);
 
        /*
         * Check that the address is valid.  If its not, refuse
@@ -989,7 +989,7 @@ static int bfin_mac_open(struct net_device *dev)
 static int bfin_mac_close(struct net_device *dev)
 {
        struct bfin_mac_local *lp = netdev_priv(dev);
-       pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+       pr_debug("%s: %s\n", dev->name, __func__);
 
        netif_stop_queue(dev);
        netif_carrier_off(dev);
index 682b8f07752941eee1bef2f8be92f8533b9047fd..edc7774f2f21312dec2bf155a98c854add82c89f 100644 (file)
@@ -6597,7 +6597,7 @@ struct flash_spec {
 
 struct bnx2_irq {
        irq_handler_t   handler;
-       u16             vector;
+       unsigned int    vector;
        u8              requested;
        char            name[16];
 };
index 3d39278a63e31fc9200395924cb0fa7d78301b37..ade5f3f6693bef27e4d006d2b370ace1956339af 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/in.h>
 #include <net/ipx.h>
 #include <net/arp.h>
+#include <net/ipv6.h>
 #include <asm/byteorder.h>
 #include "bonding.h"
 #include "bond_alb.h"
@@ -81,6 +82,7 @@
 #define RLB_PROMISC_TIMEOUT    10*ALB_TIMER_TICKS_PER_SEC
 
 static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
+static const u8 mac_v6_allmcast[ETH_ALEN] = {0x33,0x33,0x00,0x00,0x00,0x01};
 static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC;
 
 #pragma pack(1)
@@ -1290,6 +1292,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
        u32 hash_index = 0;
        const u8 *hash_start = NULL;
        int res = 1;
+       struct ipv6hdr *ip6hdr;
 
        skb_reset_mac_header(skb);
        eth_data = eth_hdr(skb);
@@ -1319,11 +1322,32 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
        }
                break;
        case ETH_P_IPV6:
+               /* IPv6 doesn't really use broadcast mac address, but leave
+                * that here just in case.
+                */
                if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) {
                        do_tx_balance = 0;
                        break;
                }
 
+               /* IPv6 uses all-nodes multicast as an equivalent to
+                * broadcasts in IPv4.
+                */
+               if (memcmp(eth_data->h_dest, mac_v6_allmcast, ETH_ALEN) == 0) {
+                       do_tx_balance = 0;
+                       break;
+               }
+
+               /* Additianally, DAD probes should not be tx-balanced as that
+                * will lead to false positives for duplicate addresses and
+                * prevent address configuration from working.
+                */
+               ip6hdr = ipv6_hdr(skb);
+               if (ipv6_addr_any(&ip6hdr->saddr)) {
+                       do_tx_balance = 0;
+                       break;
+               }
+
                hash_start = (char *)&(ipv6_hdr(skb)->daddr);
                hash_size = sizeof(ipv6_hdr(skb)->daddr);
                break;
index babe4610c39af1375ab7551da85639fe31003e71..8e2be24f3fe4c2e0f73062092a87f0b03da2f382 100644 (file)
@@ -4493,6 +4493,12 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
 
 static const struct ethtool_ops bond_ethtool_ops = {
        .get_drvinfo            = bond_ethtool_get_drvinfo,
+       .get_link               = ethtool_op_get_link,
+       .get_tx_csum            = ethtool_op_get_tx_csum,
+       .get_sg                 = ethtool_op_get_sg,
+       .get_tso                = ethtool_op_get_tso,
+       .get_ufo                = ethtool_op_get_ufo,
+       .get_flags              = ethtool_op_get_flags,
 };
 
 /*
index fb730ec0396f59b1879b5908d909e3f85a273633..ffb668dd6d3b00eddbc328513b785e42c31d492d 100644 (file)
@@ -32,7 +32,7 @@
 #ifdef BONDING_DEBUG
 #define dprintk(fmt, args...) \
        printk(KERN_DEBUG     \
-              DRV_NAME ": %s() %d: " fmt, __FUNCTION__, __LINE__ , ## args )
+              DRV_NAME ": %s() %d: " fmt, __func__, __LINE__ , ## args )
 #else
 #define dprintk(fmt, args...)
 #endif /* BONDING_DEBUG */
@@ -333,5 +333,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 void bond_register_arp(struct bonding *);
 void bond_unregister_arp(struct bonding *);
 
+/* exported from bond_main.c */
+extern struct list_head bond_dev_list;
+extern struct bond_parm_tbl bond_lacp_tbl[];
+extern struct bond_parm_tbl bond_mode_tbl[];
+extern struct bond_parm_tbl xmit_hashtype_tbl[];
+extern struct bond_parm_tbl arp_validate_tbl[];
+extern struct bond_parm_tbl fail_over_mac_tbl[];
+
 #endif /* _LINUX_BONDING_H */
 
index f1936d51b458e387e3ba0ffef867f1e388bb8a90..86909cfb14de77b458131940110d290e76c6197f 100644 (file)
@@ -74,6 +74,7 @@
 #include <linux/slab.h>
 #include <linux/delay.h>
 #include <linux/init.h>
+#include <linux/vmalloc.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/mm.h>
@@ -91,6 +92,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/mutex.h>
+#include <linux/firmware.h>
 
 #include <net/checksum.h>
 
@@ -197,6 +199,7 @@ static int link_mode;
 MODULE_AUTHOR("Adrian Sun (asun@darksunrising.com)");
 MODULE_DESCRIPTION("Sun Cassini(+) ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("sun/cassini.bin");
 module_param(cassini_debug, int, 0);
 MODULE_PARM_DESC(cassini_debug, "Cassini bitmapped debugging message enable value");
 module_param(link_mode, int, 0);
@@ -812,9 +815,44 @@ static int cas_reset_mii_phy(struct cas *cp)
        return (limit <= 0);
 }
 
+static int cas_saturn_firmware_init(struct cas *cp)
+{
+       const struct firmware *fw;
+       const char fw_name[] = "sun/cassini.bin";
+       int err;
+
+       if (PHY_NS_DP83065 != cp->phy_id)
+               return 0;
+
+       err = request_firmware(&fw, fw_name, &cp->pdev->dev);
+       if (err) {
+               printk(KERN_ERR "cassini: Failed to load firmware \"%s\"\n",
+                      fw_name);
+               return err;
+       }
+       if (fw->size < 2) {
+               printk(KERN_ERR "cassini: bogus length %zu in \"%s\"\n",
+                      fw->size, fw_name);
+               err = -EINVAL;
+               goto out;
+       }
+       cp->fw_load_addr= fw->data[1] << 8 | fw->data[0];
+       cp->fw_size = fw->size - 2;
+       cp->fw_data = vmalloc(cp->fw_size);
+       if (!cp->fw_data) {
+               err = -ENOMEM;
+               printk(KERN_ERR "cassini: \"%s\" Failed %d\n", fw_name, err);
+               goto out;
+       }
+       memcpy(cp->fw_data, &fw->data[2], cp->fw_size);
+out:
+       release_firmware(fw);
+       return err;
+}
+
 static void cas_saturn_firmware_load(struct cas *cp)
 {
-       cas_saturn_patch_t *patch = cas_saturn_patch;
+       int i;
 
        cas_phy_powerdown(cp);
 
@@ -833,11 +871,9 @@ static void cas_saturn_firmware_load(struct cas *cp)
 
        /* download new firmware */
        cas_phy_write(cp, DP83065_MII_MEM, 0x1);
-       cas_phy_write(cp, DP83065_MII_REGE, patch->addr);
-       while (patch->addr) {
-               cas_phy_write(cp, DP83065_MII_REGD, patch->val);
-               patch++;
-       }
+       cas_phy_write(cp, DP83065_MII_REGE, cp->fw_load_addr);
+       for (i = 0; i < cp->fw_size; i++)
+               cas_phy_write(cp, DP83065_MII_REGD, cp->fw_data[i]);
 
        /* enable firmware */
        cas_phy_write(cp, DP83065_MII_REGE, 0x8ff8);
@@ -2182,7 +2218,7 @@ static inline void cas_rx_flow_pkt(struct cas *cp, const u64 *words,
         * do any additional locking here. stick the buffer
         * at the end.
         */
-       __skb_insert(skb, flow->prev, (struct sk_buff *) flow, flow);
+       __skb_queue_tail(flow, skb);
        if (words[0] & RX_COMP1_RELEASE_FLOW) {
                while ((skb = __skb_dequeue(flow))) {
                        cas_skb_release(skb);
@@ -5108,6 +5144,9 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
        cas_reset(cp, 0);
        if (cas_check_invariants(cp))
                goto err_out_iounmap;
+       if (cp->cas_flags & CAS_FLAG_SATURN)
+               if (cas_saturn_firmware_init(cp))
+                       goto err_out_iounmap;
 
        cp->init_block = (struct cas_init_block *)
                pci_alloc_consistent(pdev, sizeof(struct cas_init_block),
@@ -5217,6 +5256,9 @@ static void __devexit cas_remove_one(struct pci_dev *pdev)
        cp = netdev_priv(dev);
        unregister_netdev(dev);
 
+       if (cp->fw_data)
+               vfree(cp->fw_data);
+
        mutex_lock(&cp->pm_mutex);
        flush_scheduled_work();
        if (cp->hw_running)
index 552af89ca1cf04f49165248293570132bdaa189a..fd17a002b453c7bae6acfec276f13a6b3717560e 100644 (file)
@@ -2514,1523 +2514,6 @@ static cas_hp_inst_t cas_prog_null[] = { {NULL} };
 #define CAS_HP_FIRMWARE               cas_prog_null
 #endif
 
-/* firmware patch for NS_DP83065 */
-typedef struct cas_saturn_patch {
-       u16 addr;
-       u16 val;
-} cas_saturn_patch_t;
-
-#if 1
-cas_saturn_patch_t cas_saturn_patch[] = {
-{0x8200,    0x007e}, {0x8201,    0x0082}, {0x8202,    0x0009},
-{0x8203,    0x0000}, {0x8204,    0x0000}, {0x8205,    0x0000},
-{0x8206,    0x0000}, {0x8207,    0x0000}, {0x8208,    0x0000},
-{0x8209,    0x008e}, {0x820a,    0x008e}, {0x820b,    0x00ff},
-{0x820c,    0x00ce}, {0x820d,    0x0082}, {0x820e,    0x0025},
-{0x820f,    0x00ff}, {0x8210,    0x0001}, {0x8211,    0x000f},
-{0x8212,    0x00ce}, {0x8213,    0x0084}, {0x8214,    0x0026},
-{0x8215,    0x00ff}, {0x8216,    0x0001}, {0x8217,    0x0011},
-{0x8218,    0x00ce}, {0x8219,    0x0085}, {0x821a,    0x003d},
-{0x821b,    0x00df}, {0x821c,    0x00e5}, {0x821d,    0x0086},
-{0x821e,    0x0039}, {0x821f,    0x00b7}, {0x8220,    0x008f},
-{0x8221,    0x00f8}, {0x8222,    0x007e}, {0x8223,    0x00c3},
-{0x8224,    0x00c2}, {0x8225,    0x0096}, {0x8226,    0x0047},
-{0x8227,    0x0084}, {0x8228,    0x00f3}, {0x8229,    0x008a},
-{0x822a,    0x0000}, {0x822b,    0x0097}, {0x822c,    0x0047},
-{0x822d,    0x00ce}, {0x822e,    0x0082}, {0x822f,    0x0033},
-{0x8230,    0x00ff}, {0x8231,    0x0001}, {0x8232,    0x000f},
-{0x8233,    0x0096}, {0x8234,    0x0046}, {0x8235,    0x0084},
-{0x8236,    0x000c}, {0x8237,    0x0081}, {0x8238,    0x0004},
-{0x8239,    0x0027}, {0x823a,    0x000b}, {0x823b,    0x0096},
-{0x823c,    0x0046}, {0x823d,    0x0084}, {0x823e,    0x000c},
-{0x823f,    0x0081}, {0x8240,    0x0008}, {0x8241,    0x0027},
-{0x8242,    0x0057}, {0x8243,    0x007e}, {0x8244,    0x0084},
-{0x8245,    0x0025}, {0x8246,    0x0096}, {0x8247,    0x0047},
-{0x8248,    0x0084}, {0x8249,    0x00f3}, {0x824a,    0x008a},
-{0x824b,    0x0004}, {0x824c,    0x0097}, {0x824d,    0x0047},
-{0x824e,    0x00ce}, {0x824f,    0x0082}, {0x8250,    0x0054},
-{0x8251,    0x00ff}, {0x8252,    0x0001}, {0x8253,    0x000f},
-{0x8254,    0x0096}, {0x8255,    0x0046}, {0x8256,    0x0084},
-{0x8257,    0x000c}, {0x8258,    0x0081}, {0x8259,    0x0004},
-{0x825a,    0x0026}, {0x825b,    0x0038}, {0x825c,    0x00b6},
-{0x825d,    0x0012}, {0x825e,    0x0020}, {0x825f,    0x0084},
-{0x8260,    0x0020}, {0x8261,    0x0026}, {0x8262,    0x0003},
-{0x8263,    0x007e}, {0x8264,    0x0084}, {0x8265,    0x0025},
-{0x8266,    0x0096}, {0x8267,    0x007b}, {0x8268,    0x00d6},
-{0x8269,    0x007c}, {0x826a,    0x00fe}, {0x826b,    0x008f},
-{0x826c,    0x0056}, {0x826d,    0x00bd}, {0x826e,    0x00f7},
-{0x826f,    0x00b6}, {0x8270,    0x00fe}, {0x8271,    0x008f},
-{0x8272,    0x004e}, {0x8273,    0x00bd}, {0x8274,    0x00ec},
-{0x8275,    0x008e}, {0x8276,    0x00bd}, {0x8277,    0x00fa},
-{0x8278,    0x00f7}, {0x8279,    0x00bd}, {0x827a,    0x00f7},
-{0x827b,    0x0028}, {0x827c,    0x00ce}, {0x827d,    0x0082},
-{0x827e,    0x0082}, {0x827f,    0x00ff}, {0x8280,    0x0001},
-{0x8281,    0x000f}, {0x8282,    0x0096}, {0x8283,    0x0046},
-{0x8284,    0x0084}, {0x8285,    0x000c}, {0x8286,    0x0081},
-{0x8287,    0x0004}, {0x8288,    0x0026}, {0x8289,    0x000a},
-{0x828a,    0x00b6}, {0x828b,    0x0012}, {0x828c,    0x0020},
-{0x828d,    0x0084}, {0x828e,    0x0020}, {0x828f,    0x0027},
-{0x8290,    0x00b5}, {0x8291,    0x007e}, {0x8292,    0x0084},
-{0x8293,    0x0025}, {0x8294,    0x00bd}, {0x8295,    0x00f7},
-{0x8296,    0x001f}, {0x8297,    0x007e}, {0x8298,    0x0084},
-{0x8299,    0x001f}, {0x829a,    0x0096}, {0x829b,    0x0047},
-{0x829c,    0x0084}, {0x829d,    0x00f3}, {0x829e,    0x008a},
-{0x829f,    0x0008}, {0x82a0,    0x0097}, {0x82a1,    0x0047},
-{0x82a2,    0x00de}, {0x82a3,    0x00e1}, {0x82a4,    0x00ad},
-{0x82a5,    0x0000}, {0x82a6,    0x00ce}, {0x82a7,    0x0082},
-{0x82a8,    0x00af}, {0x82a9,    0x00ff}, {0x82aa,    0x0001},
-{0x82ab,    0x000f}, {0x82ac,    0x007e}, {0x82ad,    0x0084},
-{0x82ae,    0x0025}, {0x82af,    0x0096}, {0x82b0,    0x0041},
-{0x82b1,    0x0085}, {0x82b2,    0x0010}, {0x82b3,    0x0026},
-{0x82b4,    0x0006}, {0x82b5,    0x0096}, {0x82b6,    0x0023},
-{0x82b7,    0x0085}, {0x82b8,    0x0040}, {0x82b9,    0x0027},
-{0x82ba,    0x0006}, {0x82bb,    0x00bd}, {0x82bc,    0x00ed},
-{0x82bd,    0x0000}, {0x82be,    0x007e}, {0x82bf,    0x0083},
-{0x82c0,    0x00a2}, {0x82c1,    0x00de}, {0x82c2,    0x0042},
-{0x82c3,    0x00bd}, {0x82c4,    0x00eb}, {0x82c5,    0x008e},
-{0x82c6,    0x0096}, {0x82c7,    0x0024}, {0x82c8,    0x0084},
-{0x82c9,    0x0008}, {0x82ca,    0x0027}, {0x82cb,    0x0003},
-{0x82cc,    0x007e}, {0x82cd,    0x0083}, {0x82ce,    0x00df},
-{0x82cf,    0x0096}, {0x82d0,    0x007b}, {0x82d1,    0x00d6},
-{0x82d2,    0x007c}, {0x82d3,    0x00fe}, {0x82d4,    0x008f},
-{0x82d5,    0x0056}, {0x82d6,    0x00bd}, {0x82d7,    0x00f7},
-{0x82d8,    0x00b6}, {0x82d9,    0x00fe}, {0x82da,    0x008f},
-{0x82db,    0x0050}, {0x82dc,    0x00bd}, {0x82dd,    0x00ec},
-{0x82de,    0x008e}, {0x82df,    0x00bd}, {0x82e0,    0x00fa},
-{0x82e1,    0x00f7}, {0x82e2,    0x0086}, {0x82e3,    0x0011},
-{0x82e4,    0x00c6}, {0x82e5,    0x0049}, {0x82e6,    0x00bd},
-{0x82e7,    0x00e4}, {0x82e8,    0x0012}, {0x82e9,    0x00ce},
-{0x82ea,    0x0082}, {0x82eb,    0x00ef}, {0x82ec,    0x00ff},
-{0x82ed,    0x0001}, {0x82ee,    0x000f}, {0x82ef,    0x0096},
-{0x82f0,    0x0046}, {0x82f1,    0x0084}, {0x82f2,    0x000c},
-{0x82f3,    0x0081}, {0x82f4,    0x0000}, {0x82f5,    0x0027},
-{0x82f6,    0x0017}, {0x82f7,    0x00c6}, {0x82f8,    0x0049},
-{0x82f9,    0x00bd}, {0x82fa,    0x00e4}, {0x82fb,    0x0091},
-{0x82fc,    0x0024}, {0x82fd,    0x000d}, {0x82fe,    0x00b6},
-{0x82ff,    0x0012}, {0x8300,    0x0020}, {0x8301,    0x0085},
-{0x8302,    0x0020}, {0x8303,    0x0026}, {0x8304,    0x000c},
-{0x8305,    0x00ce}, {0x8306,    0x0082}, {0x8307,    0x00c1},
-{0x8308,    0x00ff}, {0x8309,    0x0001}, {0x830a,    0x000f},
-{0x830b,    0x007e}, {0x830c,    0x0084}, {0x830d,    0x0025},
-{0x830e,    0x007e}, {0x830f,    0x0084}, {0x8310,    0x0016},
-{0x8311,    0x00fe}, {0x8312,    0x008f}, {0x8313,    0x0052},
-{0x8314,    0x00bd}, {0x8315,    0x00ec}, {0x8316,    0x008e},
-{0x8317,    0x00bd}, {0x8318,    0x00fa}, {0x8319,    0x00f7},
-{0x831a,    0x0086}, {0x831b,    0x006a}, {0x831c,    0x00c6},
-{0x831d,    0x0049}, {0x831e,    0x00bd}, {0x831f,    0x00e4},
-{0x8320,    0x0012}, {0x8321,    0x00ce}, {0x8322,    0x0083},
-{0x8323,    0x0027}, {0x8324,    0x00ff}, {0x8325,    0x0001},
-{0x8326,    0x000f}, {0x8327,    0x0096}, {0x8328,    0x0046},
-{0x8329,    0x0084}, {0x832a,    0x000c}, {0x832b,    0x0081},
-{0x832c,    0x0000}, {0x832d,    0x0027}, {0x832e,    0x000a},
-{0x832f,    0x00c6}, {0x8330,    0x0049}, {0x8331,    0x00bd},
-{0x8332,    0x00e4}, {0x8333,    0x0091}, {0x8334,    0x0025},
-{0x8335,    0x0006}, {0x8336,    0x007e}, {0x8337,    0x0084},
-{0x8338,    0x0025}, {0x8339,    0x007e}, {0x833a,    0x0084},
-{0x833b,    0x0016}, {0x833c,    0x00b6}, {0x833d,    0x0018},
-{0x833e,    0x0070}, {0x833f,    0x00bb}, {0x8340,    0x0019},
-{0x8341,    0x0070}, {0x8342,    0x002a}, {0x8343,    0x0004},
-{0x8344,    0x0081}, {0x8345,    0x00af}, {0x8346,    0x002e},
-{0x8347,    0x0019}, {0x8348,    0x0096}, {0x8349,    0x007b},
-{0x834a,    0x00f6}, {0x834b,    0x0020}, {0x834c,    0x0007},
-{0x834d,    0x00fa}, {0x834e,    0x0020}, {0x834f,    0x0027},
-{0x8350,    0x00c4}, {0x8351,    0x0038}, {0x8352,    0x0081},
-{0x8353,    0x0038}, {0x8354,    0x0027}, {0x8355,    0x000b},
-{0x8356,    0x00f6}, {0x8357,    0x0020}, {0x8358,    0x0007},
-{0x8359,    0x00fa}, {0x835a,    0x0020}, {0x835b,    0x0027},
-{0x835c,    0x00cb}, {0x835d,    0x0008}, {0x835e,    0x007e},
-{0x835f,    0x0082}, {0x8360,    0x00d3}, {0x8361,    0x00bd},
-{0x8362,    0x00f7}, {0x8363,    0x0066}, {0x8364,    0x0086},
-{0x8365,    0x0074}, {0x8366,    0x00c6}, {0x8367,    0x0049},
-{0x8368,    0x00bd}, {0x8369,    0x00e4}, {0x836a,    0x0012},
-{0x836b,    0x00ce}, {0x836c,    0x0083}, {0x836d,    0x0071},
-{0x836e,    0x00ff}, {0x836f,    0x0001}, {0x8370,    0x000f},
-{0x8371,    0x0096}, {0x8372,    0x0046}, {0x8373,    0x0084},
-{0x8374,    0x000c}, {0x8375,    0x0081}, {0x8376,    0x0008},
-{0x8377,    0x0026}, {0x8378,    0x000a}, {0x8379,    0x00c6},
-{0x837a,    0x0049}, {0x837b,    0x00bd}, {0x837c,    0x00e4},
-{0x837d,    0x0091}, {0x837e,    0x0025}, {0x837f,    0x0006},
-{0x8380,    0x007e}, {0x8381,    0x0084}, {0x8382,    0x0025},
-{0x8383,    0x007e}, {0x8384,    0x0084}, {0x8385,    0x0016},
-{0x8386,    0x00bd}, {0x8387,    0x00f7}, {0x8388,    0x003e},
-{0x8389,    0x0026}, {0x838a,    0x000e}, {0x838b,    0x00bd},
-{0x838c,    0x00e5}, {0x838d,    0x0009}, {0x838e,    0x0026},
-{0x838f,    0x0006}, {0x8390,    0x00ce}, {0x8391,    0x0082},
-{0x8392,    0x00c1}, {0x8393,    0x00ff}, {0x8394,    0x0001},
-{0x8395,    0x000f}, {0x8396,    0x007e}, {0x8397,    0x0084},
-{0x8398,    0x0025}, {0x8399,    0x00fe}, {0x839a,    0x008f},
-{0x839b,    0x0054}, {0x839c,    0x00bd}, {0x839d,    0x00ec},
-{0x839e,    0x008e}, {0x839f,    0x00bd}, {0x83a0,    0x00fa},
-{0x83a1,    0x00f7}, {0x83a2,    0x00bd}, {0x83a3,    0x00f7},
-{0x83a4,    0x0033}, {0x83a5,    0x0086}, {0x83a6,    0x000f},
-{0x83a7,    0x00c6}, {0x83a8,    0x0051}, {0x83a9,    0x00bd},
-{0x83aa,    0x00e4}, {0x83ab,    0x0012}, {0x83ac,    0x00ce},
-{0x83ad,    0x0083}, {0x83ae,    0x00b2}, {0x83af,    0x00ff},
-{0x83b0,    0x0001}, {0x83b1,    0x000f}, {0x83b2,    0x0096},
-{0x83b3,    0x0046}, {0x83b4,    0x0084}, {0x83b5,    0x000c},
-{0x83b6,    0x0081}, {0x83b7,    0x0008}, {0x83b8,    0x0026},
-{0x83b9,    0x005c}, {0x83ba,    0x00b6}, {0x83bb,    0x0012},
-{0x83bc,    0x0020}, {0x83bd,    0x0084}, {0x83be,    0x003f},
-{0x83bf,    0x0081}, {0x83c0,    0x003a}, {0x83c1,    0x0027},
-{0x83c2,    0x001c}, {0x83c3,    0x0096}, {0x83c4,    0x0023},
-{0x83c5,    0x0085}, {0x83c6,    0x0040}, {0x83c7,    0x0027},
-{0x83c8,    0x0003}, {0x83c9,    0x007e}, {0x83ca,    0x0084},
-{0x83cb,    0x0025}, {0x83cc,    0x00c6}, {0x83cd,    0x0051},
-{0x83ce,    0x00bd}, {0x83cf,    0x00e4}, {0x83d0,    0x0091},
-{0x83d1,    0x0025}, {0x83d2,    0x0003}, {0x83d3,    0x007e},
-{0x83d4,    0x0084}, {0x83d5,    0x0025}, {0x83d6,    0x00ce},
-{0x83d7,    0x0082}, {0x83d8,    0x00c1}, {0x83d9,    0x00ff},
-{0x83da,    0x0001}, {0x83db,    0x000f}, {0x83dc,    0x007e},
-{0x83dd,    0x0084}, {0x83de,    0x0025}, {0x83df,    0x00bd},
-{0x83e0,    0x00f8}, {0x83e1,    0x0037}, {0x83e2,    0x007c},
-{0x83e3,    0x0000}, {0x83e4,    0x007a}, {0x83e5,    0x00ce},
-{0x83e6,    0x0083}, {0x83e7,    0x00ee}, {0x83e8,    0x00ff},
-{0x83e9,    0x0001}, {0x83ea,    0x000f}, {0x83eb,    0x007e},
-{0x83ec,    0x0084}, {0x83ed,    0x0025}, {0x83ee,    0x0096},
-{0x83ef,    0x0046}, {0x83f0,    0x0084}, {0x83f1,    0x000c},
-{0x83f2,    0x0081}, {0x83f3,    0x0008}, {0x83f4,    0x0026},
-{0x83f5,    0x0020}, {0x83f6,    0x0096}, {0x83f7,    0x0024},
-{0x83f8,    0x0084}, {0x83f9,    0x0008}, {0x83fa,    0x0026},
-{0x83fb,    0x0029}, {0x83fc,    0x00b6}, {0x83fd,    0x0018},
-{0x83fe,    0x0082}, {0x83ff,    0x00bb}, {0x8400,    0x0019},
-{0x8401,    0x0082}, {0x8402,    0x00b1}, {0x8403,    0x0001},
-{0x8404,    0x003b}, {0x8405,    0x0022}, {0x8406,    0x0009},
-{0x8407,    0x00b6}, {0x8408,    0x0012}, {0x8409,    0x0020},
-{0x840a,    0x0084}, {0x840b,    0x0037}, {0x840c,    0x0081},
-{0x840d,    0x0032}, {0x840e,    0x0027}, {0x840f,    0x0015},
-{0x8410,    0x00bd}, {0x8411,    0x00f8}, {0x8412,    0x0044},
-{0x8413,    0x007e}, {0x8414,    0x0082}, {0x8415,    0x00c1},
-{0x8416,    0x00bd}, {0x8417,    0x00f7}, {0x8418,    0x001f},
-{0x8419,    0x00bd}, {0x841a,    0x00f8}, {0x841b,    0x0044},
-{0x841c,    0x00bd}, {0x841d,    0x00fc}, {0x841e,    0x0029},
-{0x841f,    0x00ce}, {0x8420,    0x0082}, {0x8421,    0x0025},
-{0x8422,    0x00ff}, {0x8423,    0x0001}, {0x8424,    0x000f},
-{0x8425,    0x0039}, {0x8426,    0x0096}, {0x8427,    0x0047},
-{0x8428,    0x0084}, {0x8429,    0x00fc}, {0x842a,    0x008a},
-{0x842b,    0x0000}, {0x842c,    0x0097}, {0x842d,    0x0047},
-{0x842e,    0x00ce}, {0x842f,    0x0084}, {0x8430,    0x0034},
-{0x8431,    0x00ff}, {0x8432,    0x0001}, {0x8433,    0x0011},
-{0x8434,    0x0096}, {0x8435,    0x0046}, {0x8436,    0x0084},
-{0x8437,    0x0003}, {0x8438,    0x0081}, {0x8439,    0x0002},
-{0x843a,    0x0027}, {0x843b,    0x0003}, {0x843c,    0x007e},
-{0x843d,    0x0085}, {0x843e,    0x001e}, {0x843f,    0x0096},
-{0x8440,    0x0047}, {0x8441,    0x0084}, {0x8442,    0x00fc},
-{0x8443,    0x008a}, {0x8444,    0x0002}, {0x8445,    0x0097},
-{0x8446,    0x0047}, {0x8447,    0x00de}, {0x8448,    0x00e1},
-{0x8449,    0x00ad}, {0x844a,    0x0000}, {0x844b,    0x0086},
-{0x844c,    0x0001}, {0x844d,    0x00b7}, {0x844e,    0x0012},
-{0x844f,    0x0051}, {0x8450,    0x00bd}, {0x8451,    0x00f7},
-{0x8452,    0x0014}, {0x8453,    0x00b6}, {0x8454,    0x0010},
-{0x8455,    0x0031}, {0x8456,    0x0084}, {0x8457,    0x00fd},
-{0x8458,    0x00b7}, {0x8459,    0x0010}, {0x845a,    0x0031},
-{0x845b,    0x00bd}, {0x845c,    0x00f8}, {0x845d,    0x001e},
-{0x845e,    0x0096}, {0x845f,    0x0081}, {0x8460,    0x00d6},
-{0x8461,    0x0082}, {0x8462,    0x00fe}, {0x8463,    0x008f},
-{0x8464,    0x005a}, {0x8465,    0x00bd}, {0x8466,    0x00f7},
-{0x8467,    0x00b6}, {0x8468,    0x00fe}, {0x8469,    0x008f},
-{0x846a,    0x005c}, {0x846b,    0x00bd}, {0x846c,    0x00ec},
-{0x846d,    0x008e}, {0x846e,    0x00bd}, {0x846f,    0x00fa},
-{0x8470,    0x00f7}, {0x8471,    0x0086}, {0x8472,    0x0008},
-{0x8473,    0x00d6}, {0x8474,    0x0000}, {0x8475,    0x00c5},
-{0x8476,    0x0010}, {0x8477,    0x0026}, {0x8478,    0x0002},
-{0x8479,    0x008b}, {0x847a,    0x0020}, {0x847b,    0x00c6},
-{0x847c,    0x0051}, {0x847d,    0x00bd}, {0x847e,    0x00e4},
-{0x847f,    0x0012}, {0x8480,    0x00ce}, {0x8481,    0x0084},
-{0x8482,    0x0086}, {0x8483,    0x00ff}, {0x8484,    0x0001},
-{0x8485,    0x0011}, {0x8486,    0x0096}, {0x8487,    0x0046},
-{0x8488,    0x0084}, {0x8489,    0x0003}, {0x848a,    0x0081},
-{0x848b,    0x0002}, {0x848c,    0x0027}, {0x848d,    0x0003},
-{0x848e,    0x007e}, {0x848f,    0x0085}, {0x8490,    0x000f},
-{0x8491,    0x00c6}, {0x8492,    0x0051}, {0x8493,    0x00bd},
-{0x8494,    0x00e4}, {0x8495,    0x0091}, {0x8496,    0x0025},
-{0x8497,    0x0003}, {0x8498,    0x007e}, {0x8499,    0x0085},
-{0x849a,    0x001e}, {0x849b,    0x0096}, {0x849c,    0x0044},
-{0x849d,    0x0085}, {0x849e,    0x0010}, {0x849f,    0x0026},
-{0x84a0,    0x000a}, {0x84a1,    0x00b6}, {0x84a2,    0x0012},
-{0x84a3,    0x0050}, {0x84a4,    0x00ba}, {0x84a5,    0x0001},
-{0x84a6,    0x003c}, {0x84a7,    0x0085}, {0x84a8,    0x0010},
-{0x84a9,    0x0027}, {0x84aa,    0x00a8}, {0x84ab,    0x00bd},
-{0x84ac,    0x00f7}, {0x84ad,    0x0066}, {0x84ae,    0x00ce},
-{0x84af,    0x0084}, {0x84b0,    0x00b7}, {0x84b1,    0x00ff},
-{0x84b2,    0x0001}, {0x84b3,    0x0011}, {0x84b4,    0x007e},
-{0x84b5,    0x0085}, {0x84b6,    0x001e}, {0x84b7,    0x0096},
-{0x84b8,    0x0046}, {0x84b9,    0x0084}, {0x84ba,    0x0003},
-{0x84bb,    0x0081}, {0x84bc,    0x0002}, {0x84bd,    0x0026},
-{0x84be,    0x0050}, {0x84bf,    0x00b6}, {0x84c0,    0x0012},
-{0x84c1,    0x0030}, {0x84c2,    0x0084}, {0x84c3,    0x0003},
-{0x84c4,    0x0081}, {0x84c5,    0x0001}, {0x84c6,    0x0027},
-{0x84c7,    0x0003}, {0x84c8,    0x007e}, {0x84c9,    0x0085},
-{0x84ca,    0x001e}, {0x84cb,    0x0096}, {0x84cc,    0x0044},
-{0x84cd,    0x0085}, {0x84ce,    0x0010}, {0x84cf,    0x0026},
-{0x84d0,    0x0013}, {0x84d1,    0x00b6}, {0x84d2,    0x0012},
-{0x84d3,    0x0050}, {0x84d4,    0x00ba}, {0x84d5,    0x0001},
-{0x84d6,    0x003c}, {0x84d7,    0x0085}, {0x84d8,    0x0010},
-{0x84d9,    0x0026}, {0x84da,    0x0009}, {0x84db,    0x00ce},
-{0x84dc,    0x0084}, {0x84dd,    0x0053}, {0x84de,    0x00ff},
-{0x84df,    0x0001}, {0x84e0,    0x0011}, {0x84e1,    0x007e},
-{0x84e2,    0x0085}, {0x84e3,    0x001e}, {0x84e4,    0x00b6},
-{0x84e5,    0x0010}, {0x84e6,    0x0031}, {0x84e7,    0x008a},
-{0x84e8,    0x0002}, {0x84e9,    0x00b7}, {0x84ea,    0x0010},
-{0x84eb,    0x0031}, {0x84ec,    0x00bd}, {0x84ed,    0x0085},
-{0x84ee,    0x001f}, {0x84ef,    0x00bd}, {0x84f0,    0x00f8},
-{0x84f1,    0x0037}, {0x84f2,    0x007c}, {0x84f3,    0x0000},
-{0x84f4,    0x0080}, {0x84f5,    0x00ce}, {0x84f6,    0x0084},
-{0x84f7,    0x00fe}, {0x84f8,    0x00ff}, {0x84f9,    0x0001},
-{0x84fa,    0x0011}, {0x84fb,    0x007e}, {0x84fc,    0x0085},
-{0x84fd,    0x001e}, {0x84fe,    0x0096}, {0x84ff,    0x0046},
-{0x8500,    0x0084}, {0x8501,    0x0003}, {0x8502,    0x0081},
-{0x8503,    0x0002}, {0x8504,    0x0026}, {0x8505,    0x0009},
-{0x8506,    0x00b6}, {0x8507,    0x0012}, {0x8508,    0x0030},
-{0x8509,    0x0084}, {0x850a,    0x0003}, {0x850b,    0x0081},
-{0x850c,    0x0001}, {0x850d,    0x0027}, {0x850e,    0x000f},
-{0x850f,    0x00bd}, {0x8510,    0x00f8}, {0x8511,    0x0044},
-{0x8512,    0x00bd}, {0x8513,    0x00f7}, {0x8514,    0x000b},
-{0x8515,    0x00bd}, {0x8516,    0x00fc}, {0x8517,    0x0029},
-{0x8518,    0x00ce}, {0x8519,    0x0084}, {0x851a,    0x0026},
-{0x851b,    0x00ff}, {0x851c,    0x0001}, {0x851d,    0x0011},
-{0x851e,    0x0039}, {0x851f,    0x00d6}, {0x8520,    0x0022},
-{0x8521,    0x00c4}, {0x8522,    0x000f}, {0x8523,    0x00b6},
-{0x8524,    0x0012}, {0x8525,    0x0030}, {0x8526,    0x00ba},
-{0x8527,    0x0012}, {0x8528,    0x0032}, {0x8529,    0x0084},
-{0x852a,    0x0004}, {0x852b,    0x0027}, {0x852c,    0x000d},
-{0x852d,    0x0096}, {0x852e,    0x0022}, {0x852f,    0x0085},
-{0x8530,    0x0004}, {0x8531,    0x0027}, {0x8532,    0x0005},
-{0x8533,    0x00ca}, {0x8534,    0x0010}, {0x8535,    0x007e},
-{0x8536,    0x0085}, {0x8537,    0x003a}, {0x8538,    0x00ca},
-{0x8539,    0x0020}, {0x853a,    0x00d7}, {0x853b,    0x0022},
-{0x853c,    0x0039}, {0x853d,    0x0086}, {0x853e,    0x0000},
-{0x853f,    0x0097}, {0x8540,    0x0083}, {0x8541,    0x0018},
-{0x8542,    0x00ce}, {0x8543,    0x001c}, {0x8544,    0x0000},
-{0x8545,    0x00bd}, {0x8546,    0x00eb}, {0x8547,    0x0046},
-{0x8548,    0x0096}, {0x8549,    0x0057}, {0x854a,    0x0085},
-{0x854b,    0x0001}, {0x854c,    0x0027}, {0x854d,    0x0002},
-{0x854e,    0x004f}, {0x854f,    0x0039}, {0x8550,    0x0085},
-{0x8551,    0x0002}, {0x8552,    0x0027}, {0x8553,    0x0001},
-{0x8554,    0x0039}, {0x8555,    0x007f}, {0x8556,    0x008f},
-{0x8557,    0x007d}, {0x8558,    0x0086}, {0x8559,    0x0004},
-{0x855a,    0x00b7}, {0x855b,    0x0012}, {0x855c,    0x0004},
-{0x855d,    0x0086}, {0x855e,    0x0008}, {0x855f,    0x00b7},
-{0x8560,    0x0012}, {0x8561,    0x0007}, {0x8562,    0x0086},
-{0x8563,    0x0010}, {0x8564,    0x00b7}, {0x8565,    0x0012},
-{0x8566,    0x000c}, {0x8567,    0x0086}, {0x8568,    0x0007},
-{0x8569,    0x00b7}, {0x856a,    0x0012}, {0x856b,    0x0006},
-{0x856c,    0x00b6}, {0x856d,    0x008f}, {0x856e,    0x007d},
-{0x856f,    0x00b7}, {0x8570,    0x0012}, {0x8571,    0x0070},
-{0x8572,    0x0086}, {0x8573,    0x0001}, {0x8574,    0x00ba},
-{0x8575,    0x0012}, {0x8576,    0x0004}, {0x8577,    0x00b7},
-{0x8578,    0x0012}, {0x8579,    0x0004}, {0x857a,    0x0001},
-{0x857b,    0x0001}, {0x857c,    0x0001}, {0x857d,    0x0001},
-{0x857e,    0x0001}, {0x857f,    0x0001}, {0x8580,    0x00b6},
-{0x8581,    0x0012}, {0x8582,    0x0004}, {0x8583,    0x0084},
-{0x8584,    0x00fe}, {0x8585,    0x008a}, {0x8586,    0x0002},
-{0x8587,    0x00b7}, {0x8588,    0x0012}, {0x8589,    0x0004},
-{0x858a,    0x0001}, {0x858b,    0x0001}, {0x858c,    0x0001},
-{0x858d,    0x0001}, {0x858e,    0x0001}, {0x858f,    0x0001},
-{0x8590,    0x0086}, {0x8591,    0x00fd}, {0x8592,    0x00b4},
-{0x8593,    0x0012}, {0x8594,    0x0004}, {0x8595,    0x00b7},
-{0x8596,    0x0012}, {0x8597,    0x0004}, {0x8598,    0x00b6},
-{0x8599,    0x0012}, {0x859a,    0x0000}, {0x859b,    0x0084},
-{0x859c,    0x0008}, {0x859d,    0x0081}, {0x859e,    0x0008},
-{0x859f,    0x0027}, {0x85a0,    0x0016}, {0x85a1,    0x00b6},
-{0x85a2,    0x008f}, {0x85a3,    0x007d}, {0x85a4,    0x0081},
-{0x85a5,    0x000c}, {0x85a6,    0x0027}, {0x85a7,    0x0008},
-{0x85a8,    0x008b}, {0x85a9,    0x0004}, {0x85aa,    0x00b7},
-{0x85ab,    0x008f}, {0x85ac,    0x007d}, {0x85ad,    0x007e},
-{0x85ae,    0x0085}, {0x85af,    0x006c}, {0x85b0,    0x0086},
-{0x85b1,    0x0003}, {0x85b2,    0x0097}, {0x85b3,    0x0040},
-{0x85b4,    0x007e}, {0x85b5,    0x0089}, {0x85b6,    0x006e},
-{0x85b7,    0x0086}, {0x85b8,    0x0007}, {0x85b9,    0x00b7},
-{0x85ba,    0x0012}, {0x85bb,    0x0006}, {0x85bc,    0x005f},
-{0x85bd,    0x00f7}, {0x85be,    0x008f}, {0x85bf,    0x0082},
-{0x85c0,    0x005f}, {0x85c1,    0x00f7}, {0x85c2,    0x008f},
-{0x85c3,    0x007f}, {0x85c4,    0x00f7}, {0x85c5,    0x008f},
-{0x85c6,    0x0070}, {0x85c7,    0x00f7}, {0x85c8,    0x008f},
-{0x85c9,    0x0071}, {0x85ca,    0x00f7}, {0x85cb,    0x008f},
-{0x85cc,    0x0072}, {0x85cd,    0x00f7}, {0x85ce,    0x008f},
-{0x85cf,    0x0073}, {0x85d0,    0x00f7}, {0x85d1,    0x008f},
-{0x85d2,    0x0074}, {0x85d3,    0x00f7}, {0x85d4,    0x008f},
-{0x85d5,    0x0075}, {0x85d6,    0x00f7}, {0x85d7,    0x008f},
-{0x85d8,    0x0076}, {0x85d9,    0x00f7}, {0x85da,    0x008f},
-{0x85db,    0x0077}, {0x85dc,    0x00f7}, {0x85dd,    0x008f},
-{0x85de,    0x0078}, {0x85df,    0x00f7}, {0x85e0,    0x008f},
-{0x85e1,    0x0079}, {0x85e2,    0x00f7}, {0x85e3,    0x008f},
-{0x85e4,    0x007a}, {0x85e5,    0x00f7}, {0x85e6,    0x008f},
-{0x85e7,    0x007b}, {0x85e8,    0x00b6}, {0x85e9,    0x0012},
-{0x85ea,    0x0004}, {0x85eb,    0x008a}, {0x85ec,    0x0010},
-{0x85ed,    0x00b7}, {0x85ee,    0x0012}, {0x85ef,    0x0004},
-{0x85f0,    0x0086}, {0x85f1,    0x00e4}, {0x85f2,    0x00b7},
-{0x85f3,    0x0012}, {0x85f4,    0x0070}, {0x85f5,    0x00b7},
-{0x85f6,    0x0012}, {0x85f7,    0x0007}, {0x85f8,    0x00f7},
-{0x85f9,    0x0012}, {0x85fa,    0x0005}, {0x85fb,    0x00f7},
-{0x85fc,    0x0012}, {0x85fd,    0x0009}, {0x85fe,    0x0086},
-{0x85ff,    0x0008}, {0x8600,    0x00ba}, {0x8601,    0x0012},
-{0x8602,    0x0004}, {0x8603,    0x00b7}, {0x8604,    0x0012},
-{0x8605,    0x0004}, {0x8606,    0x0086}, {0x8607,    0x00f7},
-{0x8608,    0x00b4}, {0x8609,    0x0012}, {0x860a,    0x0004},
-{0x860b,    0x00b7}, {0x860c,    0x0012}, {0x860d,    0x0004},
-{0x860e,    0x0001}, {0x860f,    0x0001}, {0x8610,    0x0001},
-{0x8611,    0x0001}, {0x8612,    0x0001}, {0x8613,    0x0001},
-{0x8614,    0x00b6}, {0x8615,    0x0012}, {0x8616,    0x0008},
-{0x8617,    0x0027}, {0x8618,    0x007f}, {0x8619,    0x0081},
-{0x861a,    0x0080}, {0x861b,    0x0026}, {0x861c,    0x000b},
-{0x861d,    0x0086}, {0x861e,    0x0008}, {0x861f,    0x00ce},
-{0x8620,    0x008f}, {0x8621,    0x0079}, {0x8622,    0x00bd},
-{0x8623,    0x0089}, {0x8624,    0x007b}, {0x8625,    0x007e},
-{0x8626,    0x0086}, {0x8627,    0x008e}, {0x8628,    0x0081},
-{0x8629,    0x0040}, {0x862a,    0x0026}, {0x862b,    0x000b},
-{0x862c,    0x0086}, {0x862d,    0x0004}, {0x862e,    0x00ce},
-{0x862f,    0x008f}, {0x8630,    0x0076}, {0x8631,    0x00bd},
-{0x8632,    0x0089}, {0x8633,    0x007b}, {0x8634,    0x007e},
-{0x8635,    0x0086}, {0x8636,    0x008e}, {0x8637,    0x0081},
-{0x8638,    0x0020}, {0x8639,    0x0026}, {0x863a,    0x000b},
-{0x863b,    0x0086}, {0x863c,    0x0002}, {0x863d,    0x00ce},
-{0x863e,    0x008f}, {0x863f,    0x0073}, {0x8640,    0x00bd},
-{0x8641,    0x0089}, {0x8642,    0x007b}, {0x8643,    0x007e},
-{0x8644,    0x0086}, {0x8645,    0x008e}, {0x8646,    0x0081},
-{0x8647,    0x0010}, {0x8648,    0x0026}, {0x8649,    0x000b},
-{0x864a,    0x0086}, {0x864b,    0x0001}, {0x864c,    0x00ce},
-{0x864d,    0x008f}, {0x864e,    0x0070}, {0x864f,    0x00bd},
-{0x8650,    0x0089}, {0x8651,    0x007b}, {0x8652,    0x007e},
-{0x8653,    0x0086}, {0x8654,    0x008e}, {0x8655,    0x0081},
-{0x8656,    0x0008}, {0x8657,    0x0026}, {0x8658,    0x000b},
-{0x8659,    0x0086}, {0x865a,    0x0008}, {0x865b,    0x00ce},
-{0x865c,    0x008f}, {0x865d,    0x0079}, {0x865e,    0x00bd},
-{0x865f,    0x0089}, {0x8660,    0x007f}, {0x8661,    0x007e},
-{0x8662,    0x0086}, {0x8663,    0x008e}, {0x8664,    0x0081},
-{0x8665,    0x0004}, {0x8666,    0x0026}, {0x8667,    0x000b},
-{0x8668,    0x0086}, {0x8669,    0x0004}, {0x866a,    0x00ce},
-{0x866b,    0x008f}, {0x866c,    0x0076}, {0x866d,    0x00bd},
-{0x866e,    0x0089}, {0x866f,    0x007f}, {0x8670,    0x007e},
-{0x8671,    0x0086}, {0x8672,    0x008e}, {0x8673,    0x0081},
-{0x8674,    0x0002}, {0x8675,    0x0026}, {0x8676,    0x000b},
-{0x8677,    0x008a}, {0x8678,    0x0002}, {0x8679,    0x00ce},
-{0x867a,    0x008f}, {0x867b,    0x0073}, {0x867c,    0x00bd},
-{0x867d,    0x0089}, {0x867e,    0x007f}, {0x867f,    0x007e},
-{0x8680,    0x0086}, {0x8681,    0x008e}, {0x8682,    0x0081},
-{0x8683,    0x0001}, {0x8684,    0x0026}, {0x8685,    0x0008},
-{0x8686,    0x0086}, {0x8687,    0x0001}, {0x8688,    0x00ce},
-{0x8689,    0x008f}, {0x868a,    0x0070}, {0x868b,    0x00bd},
-{0x868c,    0x0089}, {0x868d,    0x007f}, {0x868e,    0x00b6},
-{0x868f,    0x008f}, {0x8690,    0x007f}, {0x8691,    0x0081},
-{0x8692,    0x000f}, {0x8693,    0x0026}, {0x8694,    0x0003},
-{0x8695,    0x007e}, {0x8696,    0x0087}, {0x8697,    0x0047},
-{0x8698,    0x00b6}, {0x8699,    0x0012}, {0x869a,    0x0009},
-{0x869b,    0x0084}, {0x869c,    0x0003}, {0x869d,    0x0081},
-{0x869e,    0x0003}, {0x869f,    0x0027}, {0x86a0,    0x0006},
-{0x86a1,    0x007c}, {0x86a2,    0x0012}, {0x86a3,    0x0009},
-{0x86a4,    0x007e}, {0x86a5,    0x0085}, {0x86a6,    0x00fe},
-{0x86a7,    0x00b6}, {0x86a8,    0x0012}, {0x86a9,    0x0006},
-{0x86aa,    0x0084}, {0x86ab,    0x0007}, {0x86ac,    0x0081},
-{0x86ad,    0x0007}, {0x86ae,    0x0027}, {0x86af,    0x0008},
-{0x86b0,    0x008b}, {0x86b1,    0x0001}, {0x86b2,    0x00b7},
-{0x86b3,    0x0012}, {0x86b4,    0x0006}, {0x86b5,    0x007e},
-{0x86b6,    0x0086}, {0x86b7,    0x00d5}, {0x86b8,    0x00b6},
-{0x86b9,    0x008f}, {0x86ba,    0x0082}, {0x86bb,    0x0026},
-{0x86bc,    0x000a}, {0x86bd,    0x007c}, {0x86be,    0x008f},
-{0x86bf,    0x0082}, {0x86c0,    0x004f}, {0x86c1,    0x00b7},
-{0x86c2,    0x0012}, {0x86c3,    0x0006}, {0x86c4,    0x007e},
-{0x86c5,    0x0085}, {0x86c6,    0x00c0}, {0x86c7,    0x00b6},
-{0x86c8,    0x0012}, {0x86c9,    0x0006}, {0x86ca,    0x0084},
-{0x86cb,    0x003f}, {0x86cc,    0x0081}, {0x86cd,    0x003f},
-{0x86ce,    0x0027}, {0x86cf,    0x0010}, {0x86d0,    0x008b},
-{0x86d1,    0x0008}, {0x86d2,    0x00b7}, {0x86d3,    0x0012},
-{0x86d4,    0x0006}, {0x86d5,    0x00b6}, {0x86d6,    0x0012},
-{0x86d7,    0x0009}, {0x86d8,    0x0084}, {0x86d9,    0x00fc},
-{0x86da,    0x00b7}, {0x86db,    0x0012}, {0x86dc,    0x0009},
-{0x86dd,    0x007e}, {0x86de,    0x0085}, {0x86df,    0x00fe},
-{0x86e0,    0x00ce}, {0x86e1,    0x008f}, {0x86e2,    0x0070},
-{0x86e3,    0x0018}, {0x86e4,    0x00ce}, {0x86e5,    0x008f},
-{0x86e6,    0x0084}, {0x86e7,    0x00c6}, {0x86e8,    0x000c},
-{0x86e9,    0x00bd}, {0x86ea,    0x0089}, {0x86eb,    0x006f},
-{0x86ec,    0x00ce}, {0x86ed,    0x008f}, {0x86ee,    0x0084},
-{0x86ef,    0x0018}, {0x86f0,    0x00ce}, {0x86f1,    0x008f},
-{0x86f2,    0x0070}, {0x86f3,    0x00c6}, {0x86f4,    0x000c},
-{0x86f5,    0x00bd}, {0x86f6,    0x0089}, {0x86f7,    0x006f},
-{0x86f8,    0x00d6}, {0x86f9,    0x0083}, {0x86fa,    0x00c1},
-{0x86fb,    0x004f}, {0x86fc,    0x002d}, {0x86fd,    0x0003},
-{0x86fe,    0x007e}, {0x86ff,    0x0087}, {0x8700,    0x0040},
-{0x8701,    0x00b6}, {0x8702,    0x008f}, {0x8703,    0x007f},
-{0x8704,    0x0081}, {0x8705,    0x0007}, {0x8706,    0x0027},
-{0x8707,    0x000f}, {0x8708,    0x0081}, {0x8709,    0x000b},
-{0x870a,    0x0027}, {0x870b,    0x0015}, {0x870c,    0x0081},
-{0x870d,    0x000d}, {0x870e,    0x0027}, {0x870f,    0x001b},
-{0x8710,    0x0081}, {0x8711,    0x000e}, {0x8712,    0x0027},
-{0x8713,    0x0021}, {0x8714,    0x007e}, {0x8715,    0x0087},
-{0x8716,    0x0040}, {0x8717,    0x00f7}, {0x8718,    0x008f},
-{0x8719,    0x007b}, {0x871a,    0x0086}, {0x871b,    0x0002},
-{0x871c,    0x00b7}, {0x871d,    0x008f}, {0x871e,    0x007a},
-{0x871f,    0x0020}, {0x8720,    0x001c}, {0x8721,    0x00f7},
-{0x8722,    0x008f}, {0x8723,    0x0078}, {0x8724,    0x0086},
-{0x8725,    0x0002}, {0x8726,    0x00b7}, {0x8727,    0x008f},
-{0x8728,    0x0077}, {0x8729,    0x0020}, {0x872a,    0x0012},
-{0x872b,    0x00f7}, {0x872c,    0x008f}, {0x872d,    0x0075},
-{0x872e,    0x0086}, {0x872f,    0x0002}, {0x8730,    0x00b7},
-{0x8731,    0x008f}, {0x8732,    0x0074}, {0x8733,    0x0020},
-{0x8734,    0x0008}, {0x8735,    0x00f7}, {0x8736,    0x008f},
-{0x8737,    0x0072}, {0x8738,    0x0086}, {0x8739,    0x0002},
-{0x873a,    0x00b7}, {0x873b,    0x008f}, {0x873c,    0x0071},
-{0x873d,    0x007e}, {0x873e,    0x0087}, {0x873f,    0x0047},
-{0x8740,    0x0086}, {0x8741,    0x0004}, {0x8742,    0x0097},
-{0x8743,    0x0040}, {0x8744,    0x007e}, {0x8745,    0x0089},
-{0x8746,    0x006e}, {0x8747,    0x00ce}, {0x8748,    0x008f},
-{0x8749,    0x0072}, {0x874a,    0x00bd}, {0x874b,    0x0089},
-{0x874c,    0x00f7}, {0x874d,    0x00ce}, {0x874e,    0x008f},
-{0x874f,    0x0075}, {0x8750,    0x00bd}, {0x8751,    0x0089},
-{0x8752,    0x00f7}, {0x8753,    0x00ce}, {0x8754,    0x008f},
-{0x8755,    0x0078}, {0x8756,    0x00bd}, {0x8757,    0x0089},
-{0x8758,    0x00f7}, {0x8759,    0x00ce}, {0x875a,    0x008f},
-{0x875b,    0x007b}, {0x875c,    0x00bd}, {0x875d,    0x0089},
-{0x875e,    0x00f7}, {0x875f,    0x004f}, {0x8760,    0x00b7},
-{0x8761,    0x008f}, {0x8762,    0x007d}, {0x8763,    0x00b7},
-{0x8764,    0x008f}, {0x8765,    0x0081}, {0x8766,    0x00b6},
-{0x8767,    0x008f}, {0x8768,    0x0072}, {0x8769,    0x0027},
-{0x876a,    0x0047}, {0x876b,    0x007c}, {0x876c,    0x008f},
-{0x876d,    0x007d}, {0x876e,    0x00b6}, {0x876f,    0x008f},
-{0x8770,    0x0075}, {0x8771,    0x0027}, {0x8772,    0x003f},
-{0x8773,    0x007c}, {0x8774,    0x008f}, {0x8775,    0x007d},
-{0x8776,    0x00b6}, {0x8777,    0x008f}, {0x8778,    0x0078},
-{0x8779,    0x0027}, {0x877a,    0x0037}, {0x877b,    0x007c},
-{0x877c,    0x008f}, {0x877d,    0x007d}, {0x877e,    0x00b6},
-{0x877f,    0x008f}, {0x8780,    0x007b}, {0x8781,    0x0027},
-{0x8782,    0x002f}, {0x8783,    0x007f}, {0x8784,    0x008f},
-{0x8785,    0x007d}, {0x8786,    0x007c}, {0x8787,    0x008f},
-{0x8788,    0x0081}, {0x8789,    0x007a}, {0x878a,    0x008f},
-{0x878b,    0x0072}, {0x878c,    0x0027}, {0x878d,    0x001b},
-{0x878e,    0x007c}, {0x878f,    0x008f}, {0x8790,    0x007d},
-{0x8791,    0x007a}, {0x8792,    0x008f}, {0x8793,    0x0075},
-{0x8794,    0x0027}, {0x8795,    0x0016}, {0x8796,    0x007c},
-{0x8797,    0x008f}, {0x8798,    0x007d}, {0x8799,    0x007a},
-{0x879a,    0x008f}, {0x879b,    0x0078}, {0x879c,    0x0027},
-{0x879d,    0x0011}, {0x879e,    0x007c}, {0x879f,    0x008f},
-{0x87a0,    0x007d}, {0x87a1,    0x007a}, {0x87a2,    0x008f},
-{0x87a3,    0x007b}, {0x87a4,    0x0027}, {0x87a5,    0x000c},
-{0x87a6,    0x007e}, {0x87a7,    0x0087}, {0x87a8,    0x0083},
-{0x87a9,    0x007a}, {0x87aa,    0x008f}, {0x87ab,    0x0075},
-{0x87ac,    0x007a}, {0x87ad,    0x008f}, {0x87ae,    0x0078},
-{0x87af,    0x007a}, {0x87b0,    0x008f}, {0x87b1,    0x007b},
-{0x87b2,    0x00ce}, {0x87b3,    0x00c1}, {0x87b4,    0x00fc},
-{0x87b5,    0x00f6}, {0x87b6,    0x008f}, {0x87b7,    0x007d},
-{0x87b8,    0x003a}, {0x87b9,    0x00a6}, {0x87ba,    0x0000},
-{0x87bb,    0x00b7}, {0x87bc,    0x0012}, {0x87bd,    0x0070},
-{0x87be,    0x00b6}, {0x87bf,    0x008f}, {0x87c0,    0x0072},
-{0x87c1,    0x0026}, {0x87c2,    0x0003}, {0x87c3,    0x007e},
-{0x87c4,    0x0087}, {0x87c5,    0x00fa}, {0x87c6,    0x00b6},
-{0x87c7,    0x008f}, {0x87c8,    0x0075}, {0x87c9,    0x0026},
-{0x87ca,    0x000a}, {0x87cb,    0x0018}, {0x87cc,    0x00ce},
-{0x87cd,    0x008f}, {0x87ce,    0x0073}, {0x87cf,    0x00bd},
-{0x87d0,    0x0089}, {0x87d1,    0x00d5}, {0x87d2,    0x007e},
-{0x87d3,    0x0087}, {0x87d4,    0x00fa}, {0x87d5,    0x00b6},
-{0x87d6,    0x008f}, {0x87d7,    0x0078}, {0x87d8,    0x0026},
-{0x87d9,    0x000a}, {0x87da,    0x0018}, {0x87db,    0x00ce},
-{0x87dc,    0x008f}, {0x87dd,    0x0076}, {0x87de,    0x00bd},
-{0x87df,    0x0089}, {0x87e0,    0x00d5}, {0x87e1,    0x007e},
-{0x87e2,    0x0087}, {0x87e3,    0x00fa}, {0x87e4,    0x00b6},
-{0x87e5,    0x008f}, {0x87e6,    0x007b}, {0x87e7,    0x0026},
-{0x87e8,    0x000a}, {0x87e9,    0x0018}, {0x87ea,    0x00ce},
-{0x87eb,    0x008f}, {0x87ec,    0x0079}, {0x87ed,    0x00bd},
-{0x87ee,    0x0089}, {0x87ef,    0x00d5}, {0x87f0,    0x007e},
-{0x87f1,    0x0087}, {0x87f2,    0x00fa}, {0x87f3,    0x0086},
-{0x87f4,    0x0005}, {0x87f5,    0x0097}, {0x87f6,    0x0040},
-{0x87f7,    0x007e}, {0x87f8,    0x0089}, {0x87f9,    0x0000},
-{0x87fa,    0x00b6}, {0x87fb,    0x008f}, {0x87fc,    0x0075},
-{0x87fd,    0x0081}, {0x87fe,    0x0007}, {0x87ff,    0x002e},
-{0x8800,    0x00f2}, {0x8801,    0x00f6}, {0x8802,    0x0012},
-{0x8803,    0x0006}, {0x8804,    0x00c4}, {0x8805,    0x00f8},
-{0x8806,    0x001b}, {0x8807,    0x00b7}, {0x8808,    0x0012},
-{0x8809,    0x0006}, {0x880a,    0x00b6}, {0x880b,    0x008f},
-{0x880c,    0x0078}, {0x880d,    0x0081}, {0x880e,    0x0007},
-{0x880f,    0x002e}, {0x8810,    0x00e2}, {0x8811,    0x0048},
-{0x8812,    0x0048}, {0x8813,    0x0048}, {0x8814,    0x00f6},
-{0x8815,    0x0012}, {0x8816,    0x0006}, {0x8817,    0x00c4},
-{0x8818,    0x00c7}, {0x8819,    0x001b}, {0x881a,    0x00b7},
-{0x881b,    0x0012}, {0x881c,    0x0006}, {0x881d,    0x00b6},
-{0x881e,    0x008f}, {0x881f,    0x007b}, {0x8820,    0x0081},
-{0x8821,    0x0007}, {0x8822,    0x002e}, {0x8823,    0x00cf},
-{0x8824,    0x00f6}, {0x8825,    0x0012}, {0x8826,    0x0005},
-{0x8827,    0x00c4}, {0x8828,    0x00f8}, {0x8829,    0x001b},
-{0x882a,    0x00b7}, {0x882b,    0x0012}, {0x882c,    0x0005},
-{0x882d,    0x0086}, {0x882e,    0x0000}, {0x882f,    0x00f6},
-{0x8830,    0x008f}, {0x8831,    0x0071}, {0x8832,    0x00bd},
-{0x8833,    0x0089}, {0x8834,    0x0094}, {0x8835,    0x0086},
-{0x8836,    0x0001}, {0x8837,    0x00f6}, {0x8838,    0x008f},
-{0x8839,    0x0074}, {0x883a,    0x00bd}, {0x883b,    0x0089},
-{0x883c,    0x0094}, {0x883d,    0x0086}, {0x883e,    0x0002},
-{0x883f,    0x00f6}, {0x8840,    0x008f}, {0x8841,    0x0077},
-{0x8842,    0x00bd}, {0x8843,    0x0089}, {0x8844,    0x0094},
-{0x8845,    0x0086}, {0x8846,    0x0003}, {0x8847,    0x00f6},
-{0x8848,    0x008f}, {0x8849,    0x007a}, {0x884a,    0x00bd},
-{0x884b,    0x0089}, {0x884c,    0x0094}, {0x884d,    0x00ce},
-{0x884e,    0x008f}, {0x884f,    0x0070}, {0x8850,    0x00a6},
-{0x8851,    0x0001}, {0x8852,    0x0081}, {0x8853,    0x0001},
-{0x8854,    0x0027}, {0x8855,    0x0007}, {0x8856,    0x0081},
-{0x8857,    0x0003}, {0x8858,    0x0027}, {0x8859,    0x0003},
-{0x885a,    0x007e}, {0x885b,    0x0088}, {0x885c,    0x0066},
-{0x885d,    0x00a6}, {0x885e,    0x0000}, {0x885f,    0x00b8},
-{0x8860,    0x008f}, {0x8861,    0x0081}, {0x8862,    0x0084},
-{0x8863,    0x0001}, {0x8864,    0x0026}, {0x8865,    0x000b},
-{0x8866,    0x008c}, {0x8867,    0x008f}, {0x8868,    0x0079},
-{0x8869,    0x002c}, {0x886a,    0x000e}, {0x886b,    0x0008},
-{0x886c,    0x0008}, {0x886d,    0x0008}, {0x886e,    0x007e},
-{0x886f,    0x0088}, {0x8870,    0x0050}, {0x8871,    0x00b6},
-{0x8872,    0x0012}, {0x8873,    0x0004}, {0x8874,    0x008a},
-{0x8875,    0x0040}, {0x8876,    0x00b7}, {0x8877,    0x0012},
-{0x8878,    0x0004}, {0x8879,    0x00b6}, {0x887a,    0x0012},
-{0x887b,    0x0004}, {0x887c,    0x0084}, {0x887d,    0x00fb},
-{0x887e,    0x0084}, {0x887f,    0x00ef}, {0x8880,    0x00b7},
-{0x8881,    0x0012}, {0x8882,    0x0004}, {0x8883,    0x00b6},
-{0x8884,    0x0012}, {0x8885,    0x0007}, {0x8886,    0x0036},
-{0x8887,    0x00b6}, {0x8888,    0x008f}, {0x8889,    0x007c},
-{0x888a,    0x0048}, {0x888b,    0x0048}, {0x888c,    0x00b7},
-{0x888d,    0x0012}, {0x888e,    0x0007}, {0x888f,    0x0086},
-{0x8890,    0x0001}, {0x8891,    0x00ba}, {0x8892,    0x0012},
-{0x8893,    0x0004}, {0x8894,    0x00b7}, {0x8895,    0x0012},
-{0x8896,    0x0004}, {0x8897,    0x0001}, {0x8898,    0x0001},
-{0x8899,    0x0001}, {0x889a,    0x0001}, {0x889b,    0x0001},
-{0x889c,    0x0001}, {0x889d,    0x0086}, {0x889e,    0x00fe},
-{0x889f,    0x00b4}, {0x88a0,    0x0012}, {0x88a1,    0x0004},
-{0x88a2,    0x00b7}, {0x88a3,    0x0012}, {0x88a4,    0x0004},
-{0x88a5,    0x0086}, {0x88a6,    0x0002}, {0x88a7,    0x00ba},
-{0x88a8,    0x0012}, {0x88a9,    0x0004}, {0x88aa,    0x00b7},
-{0x88ab,    0x0012}, {0x88ac,    0x0004}, {0x88ad,    0x0086},
-{0x88ae,    0x00fd}, {0x88af,    0x00b4}, {0x88b0,    0x0012},
-{0x88b1,    0x0004}, {0x88b2,    0x00b7}, {0x88b3,    0x0012},
-{0x88b4,    0x0004}, {0x88b5,    0x0032}, {0x88b6,    0x00b7},
-{0x88b7,    0x0012}, {0x88b8,    0x0007}, {0x88b9,    0x00b6},
-{0x88ba,    0x0012}, {0x88bb,    0x0000}, {0x88bc,    0x0084},
-{0x88bd,    0x0008}, {0x88be,    0x0081}, {0x88bf,    0x0008},
-{0x88c0,    0x0027}, {0x88c1,    0x000f}, {0x88c2,    0x007c},
-{0x88c3,    0x0082}, {0x88c4,    0x0008}, {0x88c5,    0x0026},
-{0x88c6,    0x0007}, {0x88c7,    0x0086}, {0x88c8,    0x0076},
-{0x88c9,    0x0097}, {0x88ca,    0x0040}, {0x88cb,    0x007e},
-{0x88cc,    0x0089}, {0x88cd,    0x006e}, {0x88ce,    0x007e},
-{0x88cf,    0x0086}, {0x88d0,    0x00ec}, {0x88d1,    0x00b6},
-{0x88d2,    0x008f}, {0x88d3,    0x007f}, {0x88d4,    0x0081},
-{0x88d5,    0x000f}, {0x88d6,    0x0027}, {0x88d7,    0x003c},
-{0x88d8,    0x00bd}, {0x88d9,    0x00e6}, {0x88da,    0x00c7},
-{0x88db,    0x00b7}, {0x88dc,    0x0012}, {0x88dd,    0x000d},
-{0x88de,    0x00bd}, {0x88df,    0x00e6}, {0x88e0,    0x00cb},
-{0x88e1,    0x00b6}, {0x88e2,    0x0012}, {0x88e3,    0x0004},
-{0x88e4,    0x008a}, {0x88e5,    0x0020}, {0x88e6,    0x00b7},
-{0x88e7,    0x0012}, {0x88e8,    0x0004}, {0x88e9,    0x00ce},
-{0x88ea,    0x00ff}, {0x88eb,    0x00ff}, {0x88ec,    0x00b6},
-{0x88ed,    0x0012}, {0x88ee,    0x0000}, {0x88ef,    0x0081},
-{0x88f0,    0x000c}, {0x88f1,    0x0026}, {0x88f2,    0x0005},
-{0x88f3,    0x0009}, {0x88f4,    0x0026}, {0x88f5,    0x00f6},
-{0x88f6,    0x0027}, {0x88f7,    0x001c}, {0x88f8,    0x00b6},
-{0x88f9,    0x0012}, {0x88fa,    0x0004}, {0x88fb,    0x0084},
-{0x88fc,    0x00df}, {0x88fd,    0x00b7}, {0x88fe,    0x0012},
-{0x88ff,    0x0004}, {0x8900,    0x0096}, {0x8901,    0x0083},
-{0x8902,    0x0081}, {0x8903,    0x0007}, {0x8904,    0x002c},
-{0x8905,    0x0005}, {0x8906,    0x007c}, {0x8907,    0x0000},
-{0x8908,    0x0083}, {0x8909,    0x0020}, {0x890a,    0x0006},
-{0x890b,    0x0096}, {0x890c,    0x0083}, {0x890d,    0x008b},
-{0x890e,    0x0008}, {0x890f,    0x0097}, {0x8910,    0x0083},
-{0x8911,    0x007e}, {0x8912,    0x0085}, {0x8913,    0x0041},
-{0x8914,    0x007f}, {0x8915,    0x008f}, {0x8916,    0x007e},
-{0x8917,    0x0086}, {0x8918,    0x0080}, {0x8919,    0x00b7},
-{0x891a,    0x0012}, {0x891b,    0x000c}, {0x891c,    0x0086},
-{0x891d,    0x0001}, {0x891e,    0x00b7}, {0x891f,    0x008f},
-{0x8920,    0x007d}, {0x8921,    0x00b6}, {0x8922,    0x0012},
-{0x8923,    0x000c}, {0x8924,    0x0084}, {0x8925,    0x007f},
-{0x8926,    0x00b7}, {0x8927,    0x0012}, {0x8928,    0x000c},
-{0x8929,    0x008a}, {0x892a,    0x0080}, {0x892b,    0x00b7},
-{0x892c,    0x0012}, {0x892d,    0x000c}, {0x892e,    0x0086},
-{0x892f,    0x000a}, {0x8930,    0x00bd}, {0x8931,    0x008a},
-{0x8932,    0x0006}, {0x8933,    0x00b6}, {0x8934,    0x0012},
-{0x8935,    0x000a}, {0x8936,    0x002a}, {0x8937,    0x0009},
-{0x8938,    0x00b6}, {0x8939,    0x0012}, {0x893a,    0x000c},
-{0x893b,    0x00ba}, {0x893c,    0x008f}, {0x893d,    0x007d},
-{0x893e,    0x00b7}, {0x893f,    0x0012}, {0x8940,    0x000c},
-{0x8941,    0x00b6}, {0x8942,    0x008f}, {0x8943,    0x007e},
-{0x8944,    0x0081}, {0x8945,    0x0060}, {0x8946,    0x0027},
-{0x8947,    0x001a}, {0x8948,    0x008b}, {0x8949,    0x0020},
-{0x894a,    0x00b7}, {0x894b,    0x008f}, {0x894c,    0x007e},
-{0x894d,    0x00b6}, {0x894e,    0x0012}, {0x894f,    0x000c},
-{0x8950,    0x0084}, {0x8951,    0x009f}, {0x8952,    0x00ba},
-{0x8953,    0x008f}, {0x8954,    0x007e}, {0x8955,    0x00b7},
-{0x8956,    0x0012}, {0x8957,    0x000c}, {0x8958,    0x00b6},
-{0x8959,    0x008f}, {0x895a,    0x007d}, {0x895b,    0x0048},
-{0x895c,    0x00b7}, {0x895d,    0x008f}, {0x895e,    0x007d},
-{0x895f,    0x007e}, {0x8960,    0x0089}, {0x8961,    0x0021},
-{0x8962,    0x00b6}, {0x8963,    0x0012}, {0x8964,    0x0004},
-{0x8965,    0x008a}, {0x8966,    0x0020}, {0x8967,    0x00b7},
-{0x8968,    0x0012}, {0x8969,    0x0004}, {0x896a,    0x00bd},
-{0x896b,    0x008a}, {0x896c,    0x000a}, {0x896d,    0x004f},
-{0x896e,    0x0039}, {0x896f,    0x00a6}, {0x8970,    0x0000},
-{0x8971,    0x0018}, {0x8972,    0x00a7}, {0x8973,    0x0000},
-{0x8974,    0x0008}, {0x8975,    0x0018}, {0x8976,    0x0008},
-{0x8977,    0x005a}, {0x8978,    0x0026}, {0x8979,    0x00f5},
-{0x897a,    0x0039}, {0x897b,    0x0036}, {0x897c,    0x006c},
-{0x897d,    0x0000}, {0x897e,    0x0032}, {0x897f,    0x00ba},
-{0x8980,    0x008f}, {0x8981,    0x007f}, {0x8982,    0x00b7},
-{0x8983,    0x008f}, {0x8984,    0x007f}, {0x8985,    0x00b6},
-{0x8986,    0x0012}, {0x8987,    0x0009}, {0x8988,    0x0084},
-{0x8989,    0x0003}, {0x898a,    0x00a7}, {0x898b,    0x0001},
-{0x898c,    0x00b6}, {0x898d,    0x0012}, {0x898e,    0x0006},
-{0x898f,    0x0084}, {0x8990,    0x003f}, {0x8991,    0x00a7},
-{0x8992,    0x0002}, {0x8993,    0x0039}, {0x8994,    0x0036},
-{0x8995,    0x0086}, {0x8996,    0x0003}, {0x8997,    0x00b7},
-{0x8998,    0x008f}, {0x8999,    0x0080}, {0x899a,    0x0032},
-{0x899b,    0x00c1}, {0x899c,    0x0000}, {0x899d,    0x0026},
-{0x899e,    0x0006}, {0x899f,    0x00b7}, {0x89a0,    0x008f},
-{0x89a1,    0x007c}, {0x89a2,    0x007e}, {0x89a3,    0x0089},
-{0x89a4,    0x00c9}, {0x89a5,    0x00c1}, {0x89a6,    0x0001},
-{0x89a7,    0x0027}, {0x89a8,    0x0018}, {0x89a9,    0x00c1},
-{0x89aa,    0x0002}, {0x89ab,    0x0027}, {0x89ac,    0x000c},
-{0x89ad,    0x00c1}, {0x89ae,    0x0003}, {0x89af,    0x0027},
-{0x89b0,    0x0000}, {0x89b1,    0x00f6}, {0x89b2,    0x008f},
-{0x89b3,    0x0080}, {0x89b4,    0x0005}, {0x89b5,    0x0005},
-{0x89b6,    0x00f7}, {0x89b7,    0x008f}, {0x89b8,    0x0080},
-{0x89b9,    0x00f6}, {0x89ba,    0x008f}, {0x89bb,    0x0080},
-{0x89bc,    0x0005}, {0x89bd,    0x0005}, {0x89be,    0x00f7},
-{0x89bf,    0x008f}, {0x89c0,    0x0080}, {0x89c1,    0x00f6},
-{0x89c2,    0x008f}, {0x89c3,    0x0080}, {0x89c4,    0x0005},
-{0x89c5,    0x0005}, {0x89c6,    0x00f7}, {0x89c7,    0x008f},
-{0x89c8,    0x0080}, {0x89c9,    0x00f6}, {0x89ca,    0x008f},
-{0x89cb,    0x0080}, {0x89cc,    0x0053}, {0x89cd,    0x00f4},
-{0x89ce,    0x0012}, {0x89cf,    0x0007}, {0x89d0,    0x001b},
-{0x89d1,    0x00b7}, {0x89d2,    0x0012}, {0x89d3,    0x0007},
-{0x89d4,    0x0039}, {0x89d5,    0x00ce}, {0x89d6,    0x008f},
-{0x89d7,    0x0070}, {0x89d8,    0x00a6}, {0x89d9,    0x0000},
-{0x89da,    0x0018}, {0x89db,    0x00e6}, {0x89dc,    0x0000},
-{0x89dd,    0x0018}, {0x89de,    0x00a7}, {0x89df,    0x0000},
-{0x89e0,    0x00e7}, {0x89e1,    0x0000}, {0x89e2,    0x00a6},
-{0x89e3,    0x0001}, {0x89e4,    0x0018}, {0x89e5,    0x00e6},
-{0x89e6,    0x0001}, {0x89e7,    0x0018}, {0x89e8,    0x00a7},
-{0x89e9,    0x0001}, {0x89ea,    0x00e7}, {0x89eb,    0x0001},
-{0x89ec,    0x00a6}, {0x89ed,    0x0002}, {0x89ee,    0x0018},
-{0x89ef,    0x00e6}, {0x89f0,    0x0002}, {0x89f1,    0x0018},
-{0x89f2,    0x00a7}, {0x89f3,    0x0002}, {0x89f4,    0x00e7},
-{0x89f5,    0x0002}, {0x89f6,    0x0039}, {0x89f7,    0x00a6},
-{0x89f8,    0x0000}, {0x89f9,    0x0084}, {0x89fa,    0x0007},
-{0x89fb,    0x00e6}, {0x89fc,    0x0000}, {0x89fd,    0x00c4},
-{0x89fe,    0x0038}, {0x89ff,    0x0054}, {0x8a00,    0x0054},
-{0x8a01,    0x0054}, {0x8a02,    0x001b}, {0x8a03,    0x00a7},
-{0x8a04,    0x0000}, {0x8a05,    0x0039}, {0x8a06,    0x004a},
-{0x8a07,    0x0026}, {0x8a08,    0x00fd}, {0x8a09,    0x0039},
-{0x8a0a,    0x0096}, {0x8a0b,    0x0022}, {0x8a0c,    0x0084},
-{0x8a0d,    0x000f}, {0x8a0e,    0x0097}, {0x8a0f,    0x0022},
-{0x8a10,    0x0086}, {0x8a11,    0x0001}, {0x8a12,    0x00b7},
-{0x8a13,    0x008f}, {0x8a14,    0x0070}, {0x8a15,    0x00b6},
-{0x8a16,    0x0012}, {0x8a17,    0x0007}, {0x8a18,    0x00b7},
-{0x8a19,    0x008f}, {0x8a1a,    0x0071}, {0x8a1b,    0x00f6},
-{0x8a1c,    0x0012}, {0x8a1d,    0x000c}, {0x8a1e,    0x00c4},
-{0x8a1f,    0x000f}, {0x8a20,    0x00c8}, {0x8a21,    0x000f},
-{0x8a22,    0x00f7}, {0x8a23,    0x008f}, {0x8a24,    0x0072},
-{0x8a25,    0x00f6}, {0x8a26,    0x008f}, {0x8a27,    0x0072},
-{0x8a28,    0x00b6}, {0x8a29,    0x008f}, {0x8a2a,    0x0071},
-{0x8a2b,    0x0084}, {0x8a2c,    0x0003}, {0x8a2d,    0x0027},
-{0x8a2e,    0x0014}, {0x8a2f,    0x0081}, {0x8a30,    0x0001},
-{0x8a31,    0x0027}, {0x8a32,    0x001c}, {0x8a33,    0x0081},
-{0x8a34,    0x0002}, {0x8a35,    0x0027}, {0x8a36,    0x0024},
-{0x8a37,    0x00f4}, {0x8a38,    0x008f}, {0x8a39,    0x0070},
-{0x8a3a,    0x0027}, {0x8a3b,    0x002a}, {0x8a3c,    0x0096},
-{0x8a3d,    0x0022}, {0x8a3e,    0x008a}, {0x8a3f,    0x0080},
-{0x8a40,    0x007e}, {0x8a41,    0x008a}, {0x8a42,    0x0064},
-{0x8a43,    0x00f4}, {0x8a44,    0x008f}, {0x8a45,    0x0070},
-{0x8a46,    0x0027}, {0x8a47,    0x001e}, {0x8a48,    0x0096},
-{0x8a49,    0x0022}, {0x8a4a,    0x008a}, {0x8a4b,    0x0010},
-{0x8a4c,    0x007e}, {0x8a4d,    0x008a}, {0x8a4e,    0x0064},
-{0x8a4f,    0x00f4}, {0x8a50,    0x008f}, {0x8a51,    0x0070},
-{0x8a52,    0x0027}, {0x8a53,    0x0012}, {0x8a54,    0x0096},
-{0x8a55,    0x0022}, {0x8a56,    0x008a}, {0x8a57,    0x0020},
-{0x8a58,    0x007e}, {0x8a59,    0x008a}, {0x8a5a,    0x0064},
-{0x8a5b,    0x00f4}, {0x8a5c,    0x008f}, {0x8a5d,    0x0070},
-{0x8a5e,    0x0027}, {0x8a5f,    0x0006}, {0x8a60,    0x0096},
-{0x8a61,    0x0022}, {0x8a62,    0x008a}, {0x8a63,    0x0040},
-{0x8a64,    0x0097}, {0x8a65,    0x0022}, {0x8a66,    0x0074},
-{0x8a67,    0x008f}, {0x8a68,    0x0071}, {0x8a69,    0x0074},
-{0x8a6a,    0x008f}, {0x8a6b,    0x0071}, {0x8a6c,    0x0078},
-{0x8a6d,    0x008f}, {0x8a6e,    0x0070}, {0x8a6f,    0x00b6},
-{0x8a70,    0x008f}, {0x8a71,    0x0070}, {0x8a72,    0x0085},
-{0x8a73,    0x0010}, {0x8a74,    0x0027}, {0x8a75,    0x00af},
-{0x8a76,    0x00d6}, {0x8a77,    0x0022}, {0x8a78,    0x00c4},
-{0x8a79,    0x0010}, {0x8a7a,    0x0058}, {0x8a7b,    0x00b6},
-{0x8a7c,    0x0012}, {0x8a7d,    0x0070}, {0x8a7e,    0x0081},
-{0x8a7f,    0x00e4}, {0x8a80,    0x0027}, {0x8a81,    0x0036},
-{0x8a82,    0x0081}, {0x8a83,    0x00e1}, {0x8a84,    0x0026},
-{0x8a85,    0x000c}, {0x8a86,    0x0096}, {0x8a87,    0x0022},
-{0x8a88,    0x0084}, {0x8a89,    0x0020}, {0x8a8a,    0x0044},
-{0x8a8b,    0x001b}, {0x8a8c,    0x00d6}, {0x8a8d,    0x0022},
-{0x8a8e,    0x00c4}, {0x8a8f,    0x00cf}, {0x8a90,    0x0020},
-{0x8a91,    0x0023}, {0x8a92,    0x0058}, {0x8a93,    0x0081},
-{0x8a94,    0x00c6}, {0x8a95,    0x0026}, {0x8a96,    0x000d},
-{0x8a97,    0x0096}, {0x8a98,    0x0022}, {0x8a99,    0x0084},
-{0x8a9a,    0x0040}, {0x8a9b,    0x0044}, {0x8a9c,    0x0044},
-{0x8a9d,    0x001b}, {0x8a9e,    0x00d6}, {0x8a9f,    0x0022},
-{0x8aa0,    0x00c4}, {0x8aa1,    0x00af}, {0x8aa2,    0x0020},
-{0x8aa3,    0x0011}, {0x8aa4,    0x0058}, {0x8aa5,    0x0081},
-{0x8aa6,    0x0027}, {0x8aa7,    0x0026}, {0x8aa8,    0x000f},
-{0x8aa9,    0x0096}, {0x8aaa,    0x0022}, {0x8aab,    0x0084},
-{0x8aac,    0x0080}, {0x8aad,    0x0044}, {0x8aae,    0x0044},
-{0x8aaf,    0x0044}, {0x8ab0,    0x001b}, {0x8ab1,    0x00d6},
-{0x8ab2,    0x0022}, {0x8ab3,    0x00c4}, {0x8ab4,    0x006f},
-{0x8ab5,    0x001b}, {0x8ab6,    0x0097}, {0x8ab7,    0x0022},
-{0x8ab8,    0x0039}, {0x8ab9,    0x0027}, {0x8aba,    0x000c},
-{0x8abb,    0x007c}, {0x8abc,    0x0082}, {0x8abd,    0x0006},
-{0x8abe,    0x00bd}, {0x8abf,    0x00d9}, {0x8ac0,    0x00ed},
-{0x8ac1,    0x00b6}, {0x8ac2,    0x0082}, {0x8ac3,    0x0007},
-{0x8ac4,    0x007e}, {0x8ac5,    0x008a}, {0x8ac6,    0x00b9},
-{0x8ac7,    0x007f}, {0x8ac8,    0x0082}, {0x8ac9,    0x0006},
-{0x8aca,    0x0039}, { 0x0, 0x0 }
-};
-#else
-cas_saturn_patch_t cas_saturn_patch[] = {
-{0x8200,    0x007e}, {0x8201,    0x0082}, {0x8202,    0x0009},
-{0x8203,    0x0000}, {0x8204,    0x0000}, {0x8205,    0x0000},
-{0x8206,    0x0000}, {0x8207,    0x0000}, {0x8208,    0x0000},
-{0x8209,    0x008e}, {0x820a,    0x008e}, {0x820b,    0x00ff},
-{0x820c,    0x00ce}, {0x820d,    0x0082}, {0x820e,    0x0025},
-{0x820f,    0x00ff}, {0x8210,    0x0001}, {0x8211,    0x000f},
-{0x8212,    0x00ce}, {0x8213,    0x0084}, {0x8214,    0x0026},
-{0x8215,    0x00ff}, {0x8216,    0x0001}, {0x8217,    0x0011},
-{0x8218,    0x00ce}, {0x8219,    0x0085}, {0x821a,    0x003d},
-{0x821b,    0x00df}, {0x821c,    0x00e5}, {0x821d,    0x0086},
-{0x821e,    0x0039}, {0x821f,    0x00b7}, {0x8220,    0x008f},
-{0x8221,    0x00f8}, {0x8222,    0x007e}, {0x8223,    0x00c3},
-{0x8224,    0x00c2}, {0x8225,    0x0096}, {0x8226,    0x0047},
-{0x8227,    0x0084}, {0x8228,    0x00f3}, {0x8229,    0x008a},
-{0x822a,    0x0000}, {0x822b,    0x0097}, {0x822c,    0x0047},
-{0x822d,    0x00ce}, {0x822e,    0x0082}, {0x822f,    0x0033},
-{0x8230,    0x00ff}, {0x8231,    0x0001}, {0x8232,    0x000f},
-{0x8233,    0x0096}, {0x8234,    0x0046}, {0x8235,    0x0084},
-{0x8236,    0x000c}, {0x8237,    0x0081}, {0x8238,    0x0004},
-{0x8239,    0x0027}, {0x823a,    0x000b}, {0x823b,    0x0096},
-{0x823c,    0x0046}, {0x823d,    0x0084}, {0x823e,    0x000c},
-{0x823f,    0x0081}, {0x8240,    0x0008}, {0x8241,    0x0027},
-{0x8242,    0x0057}, {0x8243,    0x007e}, {0x8244,    0x0084},
-{0x8245,    0x0025}, {0x8246,    0x0096}, {0x8247,    0x0047},
-{0x8248,    0x0084}, {0x8249,    0x00f3}, {0x824a,    0x008a},
-{0x824b,    0x0004}, {0x824c,    0x0097}, {0x824d,    0x0047},
-{0x824e,    0x00ce}, {0x824f,    0x0082}, {0x8250,    0x0054},
-{0x8251,    0x00ff}, {0x8252,    0x0001}, {0x8253,    0x000f},
-{0x8254,    0x0096}, {0x8255,    0x0046}, {0x8256,    0x0084},
-{0x8257,    0x000c}, {0x8258,    0x0081}, {0x8259,    0x0004},
-{0x825a,    0x0026}, {0x825b,    0x0038}, {0x825c,    0x00b6},
-{0x825d,    0x0012}, {0x825e,    0x0020}, {0x825f,    0x0084},
-{0x8260,    0x0020}, {0x8261,    0x0026}, {0x8262,    0x0003},
-{0x8263,    0x007e}, {0x8264,    0x0084}, {0x8265,    0x0025},
-{0x8266,    0x0096}, {0x8267,    0x007b}, {0x8268,    0x00d6},
-{0x8269,    0x007c}, {0x826a,    0x00fe}, {0x826b,    0x008f},
-{0x826c,    0x0056}, {0x826d,    0x00bd}, {0x826e,    0x00f7},
-{0x826f,    0x00b6}, {0x8270,    0x00fe}, {0x8271,    0x008f},
-{0x8272,    0x004e}, {0x8273,    0x00bd}, {0x8274,    0x00ec},
-{0x8275,    0x008e}, {0x8276,    0x00bd}, {0x8277,    0x00fa},
-{0x8278,    0x00f7}, {0x8279,    0x00bd}, {0x827a,    0x00f7},
-{0x827b,    0x0028}, {0x827c,    0x00ce}, {0x827d,    0x0082},
-{0x827e,    0x0082}, {0x827f,    0x00ff}, {0x8280,    0x0001},
-{0x8281,    0x000f}, {0x8282,    0x0096}, {0x8283,    0x0046},
-{0x8284,    0x0084}, {0x8285,    0x000c}, {0x8286,    0x0081},
-{0x8287,    0x0004}, {0x8288,    0x0026}, {0x8289,    0x000a},
-{0x828a,    0x00b6}, {0x828b,    0x0012}, {0x828c,    0x0020},
-{0x828d,    0x0084}, {0x828e,    0x0020}, {0x828f,    0x0027},
-{0x8290,    0x00b5}, {0x8291,    0x007e}, {0x8292,    0x0084},
-{0x8293,    0x0025}, {0x8294,    0x00bd}, {0x8295,    0x00f7},
-{0x8296,    0x001f}, {0x8297,    0x007e}, {0x8298,    0x0084},
-{0x8299,    0x001f}, {0x829a,    0x0096}, {0x829b,    0x0047},
-{0x829c,    0x0084}, {0x829d,    0x00f3}, {0x829e,    0x008a},
-{0x829f,    0x0008}, {0x82a0,    0x0097}, {0x82a1,    0x0047},
-{0x82a2,    0x00de}, {0x82a3,    0x00e1}, {0x82a4,    0x00ad},
-{0x82a5,    0x0000}, {0x82a6,    0x00ce}, {0x82a7,    0x0082},
-{0x82a8,    0x00af}, {0x82a9,    0x00ff}, {0x82aa,    0x0001},
-{0x82ab,    0x000f}, {0x82ac,    0x007e}, {0x82ad,    0x0084},
-{0x82ae,    0x0025}, {0x82af,    0x0096}, {0x82b0,    0x0041},
-{0x82b1,    0x0085}, {0x82b2,    0x0010}, {0x82b3,    0x0026},
-{0x82b4,    0x0006}, {0x82b5,    0x0096}, {0x82b6,    0x0023},
-{0x82b7,    0x0085}, {0x82b8,    0x0040}, {0x82b9,    0x0027},
-{0x82ba,    0x0006}, {0x82bb,    0x00bd}, {0x82bc,    0x00ed},
-{0x82bd,    0x0000}, {0x82be,    0x007e}, {0x82bf,    0x0083},
-{0x82c0,    0x00a2}, {0x82c1,    0x00de}, {0x82c2,    0x0042},
-{0x82c3,    0x00bd}, {0x82c4,    0x00eb}, {0x82c5,    0x008e},
-{0x82c6,    0x0096}, {0x82c7,    0x0024}, {0x82c8,    0x0084},
-{0x82c9,    0x0008}, {0x82ca,    0x0027}, {0x82cb,    0x0003},
-{0x82cc,    0x007e}, {0x82cd,    0x0083}, {0x82ce,    0x00df},
-{0x82cf,    0x0096}, {0x82d0,    0x007b}, {0x82d1,    0x00d6},
-{0x82d2,    0x007c}, {0x82d3,    0x00fe}, {0x82d4,    0x008f},
-{0x82d5,    0x0056}, {0x82d6,    0x00bd}, {0x82d7,    0x00f7},
-{0x82d8,    0x00b6}, {0x82d9,    0x00fe}, {0x82da,    0x008f},
-{0x82db,    0x0050}, {0x82dc,    0x00bd}, {0x82dd,    0x00ec},
-{0x82de,    0x008e}, {0x82df,    0x00bd}, {0x82e0,    0x00fa},
-{0x82e1,    0x00f7}, {0x82e2,    0x0086}, {0x82e3,    0x0011},
-{0x82e4,    0x00c6}, {0x82e5,    0x0049}, {0x82e6,    0x00bd},
-{0x82e7,    0x00e4}, {0x82e8,    0x0012}, {0x82e9,    0x00ce},
-{0x82ea,    0x0082}, {0x82eb,    0x00ef}, {0x82ec,    0x00ff},
-{0x82ed,    0x0001}, {0x82ee,    0x000f}, {0x82ef,    0x0096},
-{0x82f0,    0x0046}, {0x82f1,    0x0084}, {0x82f2,    0x000c},
-{0x82f3,    0x0081}, {0x82f4,    0x0000}, {0x82f5,    0x0027},
-{0x82f6,    0x0017}, {0x82f7,    0x00c6}, {0x82f8,    0x0049},
-{0x82f9,    0x00bd}, {0x82fa,    0x00e4}, {0x82fb,    0x0091},
-{0x82fc,    0x0024}, {0x82fd,    0x000d}, {0x82fe,    0x00b6},
-{0x82ff,    0x0012}, {0x8300,    0x0020}, {0x8301,    0x0085},
-{0x8302,    0x0020}, {0x8303,    0x0026}, {0x8304,    0x000c},
-{0x8305,    0x00ce}, {0x8306,    0x0082}, {0x8307,    0x00c1},
-{0x8308,    0x00ff}, {0x8309,    0x0001}, {0x830a,    0x000f},
-{0x830b,    0x007e}, {0x830c,    0x0084}, {0x830d,    0x0025},
-{0x830e,    0x007e}, {0x830f,    0x0084}, {0x8310,    0x0016},
-{0x8311,    0x00fe}, {0x8312,    0x008f}, {0x8313,    0x0052},
-{0x8314,    0x00bd}, {0x8315,    0x00ec}, {0x8316,    0x008e},
-{0x8317,    0x00bd}, {0x8318,    0x00fa}, {0x8319,    0x00f7},
-{0x831a,    0x0086}, {0x831b,    0x006a}, {0x831c,    0x00c6},
-{0x831d,    0x0049}, {0x831e,    0x00bd}, {0x831f,    0x00e4},
-{0x8320,    0x0012}, {0x8321,    0x00ce}, {0x8322,    0x0083},
-{0x8323,    0x0027}, {0x8324,    0x00ff}, {0x8325,    0x0001},
-{0x8326,    0x000f}, {0x8327,    0x0096}, {0x8328,    0x0046},
-{0x8329,    0x0084}, {0x832a,    0x000c}, {0x832b,    0x0081},
-{0x832c,    0x0000}, {0x832d,    0x0027}, {0x832e,    0x000a},
-{0x832f,    0x00c6}, {0x8330,    0x0049}, {0x8331,    0x00bd},
-{0x8332,    0x00e4}, {0x8333,    0x0091}, {0x8334,    0x0025},
-{0x8335,    0x0006}, {0x8336,    0x007e}, {0x8337,    0x0084},
-{0x8338,    0x0025}, {0x8339,    0x007e}, {0x833a,    0x0084},
-{0x833b,    0x0016}, {0x833c,    0x00b6}, {0x833d,    0x0018},
-{0x833e,    0x0070}, {0x833f,    0x00bb}, {0x8340,    0x0019},
-{0x8341,    0x0070}, {0x8342,    0x002a}, {0x8343,    0x0004},
-{0x8344,    0x0081}, {0x8345,    0x00af}, {0x8346,    0x002e},
-{0x8347,    0x0019}, {0x8348,    0x0096}, {0x8349,    0x007b},
-{0x834a,    0x00f6}, {0x834b,    0x0020}, {0x834c,    0x0007},
-{0x834d,    0x00fa}, {0x834e,    0x0020}, {0x834f,    0x0027},
-{0x8350,    0x00c4}, {0x8351,    0x0038}, {0x8352,    0x0081},
-{0x8353,    0x0038}, {0x8354,    0x0027}, {0x8355,    0x000b},
-{0x8356,    0x00f6}, {0x8357,    0x0020}, {0x8358,    0x0007},
-{0x8359,    0x00fa}, {0x835a,    0x0020}, {0x835b,    0x0027},
-{0x835c,    0x00cb}, {0x835d,    0x0008}, {0x835e,    0x007e},
-{0x835f,    0x0082}, {0x8360,    0x00d3}, {0x8361,    0x00bd},
-{0x8362,    0x00f7}, {0x8363,    0x0066}, {0x8364,    0x0086},
-{0x8365,    0x0074}, {0x8366,    0x00c6}, {0x8367,    0x0049},
-{0x8368,    0x00bd}, {0x8369,    0x00e4}, {0x836a,    0x0012},
-{0x836b,    0x00ce}, {0x836c,    0x0083}, {0x836d,    0x0071},
-{0x836e,    0x00ff}, {0x836f,    0x0001}, {0x8370,    0x000f},
-{0x8371,    0x0096}, {0x8372,    0x0046}, {0x8373,    0x0084},
-{0x8374,    0x000c}, {0x8375,    0x0081}, {0x8376,    0x0008},
-{0x8377,    0x0026}, {0x8378,    0x000a}, {0x8379,    0x00c6},
-{0x837a,    0x0049}, {0x837b,    0x00bd}, {0x837c,    0x00e4},
-{0x837d,    0x0091}, {0x837e,    0x0025}, {0x837f,    0x0006},
-{0x8380,    0x007e}, {0x8381,    0x0084}, {0x8382,    0x0025},
-{0x8383,    0x007e}, {0x8384,    0x0084}, {0x8385,    0x0016},
-{0x8386,    0x00bd}, {0x8387,    0x00f7}, {0x8388,    0x003e},
-{0x8389,    0x0026}, {0x838a,    0x000e}, {0x838b,    0x00bd},
-{0x838c,    0x00e5}, {0x838d,    0x0009}, {0x838e,    0x0026},
-{0x838f,    0x0006}, {0x8390,    0x00ce}, {0x8391,    0x0082},
-{0x8392,    0x00c1}, {0x8393,    0x00ff}, {0x8394,    0x0001},
-{0x8395,    0x000f}, {0x8396,    0x007e}, {0x8397,    0x0084},
-{0x8398,    0x0025}, {0x8399,    0x00fe}, {0x839a,    0x008f},
-{0x839b,    0x0054}, {0x839c,    0x00bd}, {0x839d,    0x00ec},
-{0x839e,    0x008e}, {0x839f,    0x00bd}, {0x83a0,    0x00fa},
-{0x83a1,    0x00f7}, {0x83a2,    0x00bd}, {0x83a3,    0x00f7},
-{0x83a4,    0x0033}, {0x83a5,    0x0086}, {0x83a6,    0x000f},
-{0x83a7,    0x00c6}, {0x83a8,    0x0051}, {0x83a9,    0x00bd},
-{0x83aa,    0x00e4}, {0x83ab,    0x0012}, {0x83ac,    0x00ce},
-{0x83ad,    0x0083}, {0x83ae,    0x00b2}, {0x83af,    0x00ff},
-{0x83b0,    0x0001}, {0x83b1,    0x000f}, {0x83b2,    0x0096},
-{0x83b3,    0x0046}, {0x83b4,    0x0084}, {0x83b5,    0x000c},
-{0x83b6,    0x0081}, {0x83b7,    0x0008}, {0x83b8,    0x0026},
-{0x83b9,    0x005c}, {0x83ba,    0x00b6}, {0x83bb,    0x0012},
-{0x83bc,    0x0020}, {0x83bd,    0x0084}, {0x83be,    0x003f},
-{0x83bf,    0x0081}, {0x83c0,    0x003a}, {0x83c1,    0x0027},
-{0x83c2,    0x001c}, {0x83c3,    0x0096}, {0x83c4,    0x0023},
-{0x83c5,    0x0085}, {0x83c6,    0x0040}, {0x83c7,    0x0027},
-{0x83c8,    0x0003}, {0x83c9,    0x007e}, {0x83ca,    0x0084},
-{0x83cb,    0x0025}, {0x83cc,    0x00c6}, {0x83cd,    0x0051},
-{0x83ce,    0x00bd}, {0x83cf,    0x00e4}, {0x83d0,    0x0091},
-{0x83d1,    0x0025}, {0x83d2,    0x0003}, {0x83d3,    0x007e},
-{0x83d4,    0x0084}, {0x83d5,    0x0025}, {0x83d6,    0x00ce},
-{0x83d7,    0x0082}, {0x83d8,    0x00c1}, {0x83d9,    0x00ff},
-{0x83da,    0x0001}, {0x83db,    0x000f}, {0x83dc,    0x007e},
-{0x83dd,    0x0084}, {0x83de,    0x0025}, {0x83df,    0x00bd},
-{0x83e0,    0x00f8}, {0x83e1,    0x0037}, {0x83e2,    0x007c},
-{0x83e3,    0x0000}, {0x83e4,    0x007a}, {0x83e5,    0x00ce},
-{0x83e6,    0x0083}, {0x83e7,    0x00ee}, {0x83e8,    0x00ff},
-{0x83e9,    0x0001}, {0x83ea,    0x000f}, {0x83eb,    0x007e},
-{0x83ec,    0x0084}, {0x83ed,    0x0025}, {0x83ee,    0x0096},
-{0x83ef,    0x0046}, {0x83f0,    0x0084}, {0x83f1,    0x000c},
-{0x83f2,    0x0081}, {0x83f3,    0x0008}, {0x83f4,    0x0026},
-{0x83f5,    0x0020}, {0x83f6,    0x0096}, {0x83f7,    0x0024},
-{0x83f8,    0x0084}, {0x83f9,    0x0008}, {0x83fa,    0x0026},
-{0x83fb,    0x0029}, {0x83fc,    0x00b6}, {0x83fd,    0x0018},
-{0x83fe,    0x0082}, {0x83ff,    0x00bb}, {0x8400,    0x0019},
-{0x8401,    0x0082}, {0x8402,    0x00b1}, {0x8403,    0x0001},
-{0x8404,    0x003b}, {0x8405,    0x0022}, {0x8406,    0x0009},
-{0x8407,    0x00b6}, {0x8408,    0x0012}, {0x8409,    0x0020},
-{0x840a,    0x0084}, {0x840b,    0x0037}, {0x840c,    0x0081},
-{0x840d,    0x0032}, {0x840e,    0x0027}, {0x840f,    0x0015},
-{0x8410,    0x00bd}, {0x8411,    0x00f8}, {0x8412,    0x0044},
-{0x8413,    0x007e}, {0x8414,    0x0082}, {0x8415,    0x00c1},
-{0x8416,    0x00bd}, {0x8417,    0x00f7}, {0x8418,    0x001f},
-{0x8419,    0x00bd}, {0x841a,    0x00f8}, {0x841b,    0x0044},
-{0x841c,    0x00bd}, {0x841d,    0x00fc}, {0x841e,    0x0029},
-{0x841f,    0x00ce}, {0x8420,    0x0082}, {0x8421,    0x0025},
-{0x8422,    0x00ff}, {0x8423,    0x0001}, {0x8424,    0x000f},
-{0x8425,    0x0039}, {0x8426,    0x0096}, {0x8427,    0x0047},
-{0x8428,    0x0084}, {0x8429,    0x00fc}, {0x842a,    0x008a},
-{0x842b,    0x0000}, {0x842c,    0x0097}, {0x842d,    0x0047},
-{0x842e,    0x00ce}, {0x842f,    0x0084}, {0x8430,    0x0034},
-{0x8431,    0x00ff}, {0x8432,    0x0001}, {0x8433,    0x0011},
-{0x8434,    0x0096}, {0x8435,    0x0046}, {0x8436,    0x0084},
-{0x8437,    0x0003}, {0x8438,    0x0081}, {0x8439,    0x0002},
-{0x843a,    0x0027}, {0x843b,    0x0003}, {0x843c,    0x007e},
-{0x843d,    0x0085}, {0x843e,    0x001e}, {0x843f,    0x0096},
-{0x8440,    0x0047}, {0x8441,    0x0084}, {0x8442,    0x00fc},
-{0x8443,    0x008a}, {0x8444,    0x0002}, {0x8445,    0x0097},
-{0x8446,    0x0047}, {0x8447,    0x00de}, {0x8448,    0x00e1},
-{0x8449,    0x00ad}, {0x844a,    0x0000}, {0x844b,    0x0086},
-{0x844c,    0x0001}, {0x844d,    0x00b7}, {0x844e,    0x0012},
-{0x844f,    0x0051}, {0x8450,    0x00bd}, {0x8451,    0x00f7},
-{0x8452,    0x0014}, {0x8453,    0x00b6}, {0x8454,    0x0010},
-{0x8455,    0x0031}, {0x8456,    0x0084}, {0x8457,    0x00fd},
-{0x8458,    0x00b7}, {0x8459,    0x0010}, {0x845a,    0x0031},
-{0x845b,    0x00bd}, {0x845c,    0x00f8}, {0x845d,    0x001e},
-{0x845e,    0x0096}, {0x845f,    0x0081}, {0x8460,    0x00d6},
-{0x8461,    0x0082}, {0x8462,    0x00fe}, {0x8463,    0x008f},
-{0x8464,    0x005a}, {0x8465,    0x00bd}, {0x8466,    0x00f7},
-{0x8467,    0x00b6}, {0x8468,    0x00fe}, {0x8469,    0x008f},
-{0x846a,    0x005c}, {0x846b,    0x00bd}, {0x846c,    0x00ec},
-{0x846d,    0x008e}, {0x846e,    0x00bd}, {0x846f,    0x00fa},
-{0x8470,    0x00f7}, {0x8471,    0x0086}, {0x8472,    0x0008},
-{0x8473,    0x00d6}, {0x8474,    0x0000}, {0x8475,    0x00c5},
-{0x8476,    0x0010}, {0x8477,    0x0026}, {0x8478,    0x0002},
-{0x8479,    0x008b}, {0x847a,    0x0020}, {0x847b,    0x00c6},
-{0x847c,    0x0051}, {0x847d,    0x00bd}, {0x847e,    0x00e4},
-{0x847f,    0x0012}, {0x8480,    0x00ce}, {0x8481,    0x0084},
-{0x8482,    0x0086}, {0x8483,    0x00ff}, {0x8484,    0x0001},
-{0x8485,    0x0011}, {0x8486,    0x0096}, {0x8487,    0x0046},
-{0x8488,    0x0084}, {0x8489,    0x0003}, {0x848a,    0x0081},
-{0x848b,    0x0002}, {0x848c,    0x0027}, {0x848d,    0x0003},
-{0x848e,    0x007e}, {0x848f,    0x0085}, {0x8490,    0x000f},
-{0x8491,    0x00c6}, {0x8492,    0x0051}, {0x8493,    0x00bd},
-{0x8494,    0x00e4}, {0x8495,    0x0091}, {0x8496,    0x0025},
-{0x8497,    0x0003}, {0x8498,    0x007e}, {0x8499,    0x0085},
-{0x849a,    0x001e}, {0x849b,    0x0096}, {0x849c,    0x0044},
-{0x849d,    0x0085}, {0x849e,    0x0010}, {0x849f,    0x0026},
-{0x84a0,    0x000a}, {0x84a1,    0x00b6}, {0x84a2,    0x0012},
-{0x84a3,    0x0050}, {0x84a4,    0x00ba}, {0x84a5,    0x0001},
-{0x84a6,    0x003c}, {0x84a7,    0x0085}, {0x84a8,    0x0010},
-{0x84a9,    0x0027}, {0x84aa,    0x00a8}, {0x84ab,    0x00bd},
-{0x84ac,    0x00f7}, {0x84ad,    0x0066}, {0x84ae,    0x00ce},
-{0x84af,    0x0084}, {0x84b0,    0x00b7}, {0x84b1,    0x00ff},
-{0x84b2,    0x0001}, {0x84b3,    0x0011}, {0x84b4,    0x007e},
-{0x84b5,    0x0085}, {0x84b6,    0x001e}, {0x84b7,    0x0096},
-{0x84b8,    0x0046}, {0x84b9,    0x0084}, {0x84ba,    0x0003},
-{0x84bb,    0x0081}, {0x84bc,    0x0002}, {0x84bd,    0x0026},
-{0x84be,    0x0050}, {0x84bf,    0x00b6}, {0x84c0,    0x0012},
-{0x84c1,    0x0030}, {0x84c2,    0x0084}, {0x84c3,    0x0003},
-{0x84c4,    0x0081}, {0x84c5,    0x0001}, {0x84c6,    0x0027},
-{0x84c7,    0x0003}, {0x84c8,    0x007e}, {0x84c9,    0x0085},
-{0x84ca,    0x001e}, {0x84cb,    0x0096}, {0x84cc,    0x0044},
-{0x84cd,    0x0085}, {0x84ce,    0x0010}, {0x84cf,    0x0026},
-{0x84d0,    0x0013}, {0x84d1,    0x00b6}, {0x84d2,    0x0012},
-{0x84d3,    0x0050}, {0x84d4,    0x00ba}, {0x84d5,    0x0001},
-{0x84d6,    0x003c}, {0x84d7,    0x0085}, {0x84d8,    0x0010},
-{0x84d9,    0x0026}, {0x84da,    0x0009}, {0x84db,    0x00ce},
-{0x84dc,    0x0084}, {0x84dd,    0x0053}, {0x84de,    0x00ff},
-{0x84df,    0x0001}, {0x84e0,    0x0011}, {0x84e1,    0x007e},
-{0x84e2,    0x0085}, {0x84e3,    0x001e}, {0x84e4,    0x00b6},
-{0x84e5,    0x0010}, {0x84e6,    0x0031}, {0x84e7,    0x008a},
-{0x84e8,    0x0002}, {0x84e9,    0x00b7}, {0x84ea,    0x0010},
-{0x84eb,    0x0031}, {0x84ec,    0x00bd}, {0x84ed,    0x0085},
-{0x84ee,    0x001f}, {0x84ef,    0x00bd}, {0x84f0,    0x00f8},
-{0x84f1,    0x0037}, {0x84f2,    0x007c}, {0x84f3,    0x0000},
-{0x84f4,    0x0080}, {0x84f5,    0x00ce}, {0x84f6,    0x0084},
-{0x84f7,    0x00fe}, {0x84f8,    0x00ff}, {0x84f9,    0x0001},
-{0x84fa,    0x0011}, {0x84fb,    0x007e}, {0x84fc,    0x0085},
-{0x84fd,    0x001e}, {0x84fe,    0x0096}, {0x84ff,    0x0046},
-{0x8500,    0x0084}, {0x8501,    0x0003}, {0x8502,    0x0081},
-{0x8503,    0x0002}, {0x8504,    0x0026}, {0x8505,    0x0009},
-{0x8506,    0x00b6}, {0x8507,    0x0012}, {0x8508,    0x0030},
-{0x8509,    0x0084}, {0x850a,    0x0003}, {0x850b,    0x0081},
-{0x850c,    0x0001}, {0x850d,    0x0027}, {0x850e,    0x000f},
-{0x850f,    0x00bd}, {0x8510,    0x00f8}, {0x8511,    0x0044},
-{0x8512,    0x00bd}, {0x8513,    0x00f7}, {0x8514,    0x000b},
-{0x8515,    0x00bd}, {0x8516,    0x00fc}, {0x8517,    0x0029},
-{0x8518,    0x00ce}, {0x8519,    0x0084}, {0x851a,    0x0026},
-{0x851b,    0x00ff}, {0x851c,    0x0001}, {0x851d,    0x0011},
-{0x851e,    0x0039}, {0x851f,    0x00d6}, {0x8520,    0x0022},
-{0x8521,    0x00c4}, {0x8522,    0x000f}, {0x8523,    0x00b6},
-{0x8524,    0x0012}, {0x8525,    0x0030}, {0x8526,    0x00ba},
-{0x8527,    0x0012}, {0x8528,    0x0032}, {0x8529,    0x0084},
-{0x852a,    0x0004}, {0x852b,    0x0027}, {0x852c,    0x000d},
-{0x852d,    0x0096}, {0x852e,    0x0022}, {0x852f,    0x0085},
-{0x8530,    0x0004}, {0x8531,    0x0027}, {0x8532,    0x0005},
-{0x8533,    0x00ca}, {0x8534,    0x0010}, {0x8535,    0x007e},
-{0x8536,    0x0085}, {0x8537,    0x003a}, {0x8538,    0x00ca},
-{0x8539,    0x0020}, {0x853a,    0x00d7}, {0x853b,    0x0022},
-{0x853c,    0x0039}, {0x853d,    0x0086}, {0x853e,    0x0000},
-{0x853f,    0x0097}, {0x8540,    0x0083}, {0x8541,    0x0018},
-{0x8542,    0x00ce}, {0x8543,    0x001c}, {0x8544,    0x0000},
-{0x8545,    0x00bd}, {0x8546,    0x00eb}, {0x8547,    0x0046},
-{0x8548,    0x0096}, {0x8549,    0x0057}, {0x854a,    0x0085},
-{0x854b,    0x0001}, {0x854c,    0x0027}, {0x854d,    0x0002},
-{0x854e,    0x004f}, {0x854f,    0x0039}, {0x8550,    0x0085},
-{0x8551,    0x0002}, {0x8552,    0x0027}, {0x8553,    0x0001},
-{0x8554,    0x0039}, {0x8555,    0x007f}, {0x8556,    0x008f},
-{0x8557,    0x007d}, {0x8558,    0x0086}, {0x8559,    0x0004},
-{0x855a,    0x00b7}, {0x855b,    0x0012}, {0x855c,    0x0004},
-{0x855d,    0x0086}, {0x855e,    0x0008}, {0x855f,    0x00b7},
-{0x8560,    0x0012}, {0x8561,    0x0007}, {0x8562,    0x0086},
-{0x8563,    0x0010}, {0x8564,    0x00b7}, {0x8565,    0x0012},
-{0x8566,    0x000c}, {0x8567,    0x0086}, {0x8568,    0x0007},
-{0x8569,    0x00b7}, {0x856a,    0x0012}, {0x856b,    0x0006},
-{0x856c,    0x00b6}, {0x856d,    0x008f}, {0x856e,    0x007d},
-{0x856f,    0x00b7}, {0x8570,    0x0012}, {0x8571,    0x0070},
-{0x8572,    0x0086}, {0x8573,    0x0001}, {0x8574,    0x00ba},
-{0x8575,    0x0012}, {0x8576,    0x0004}, {0x8577,    0x00b7},
-{0x8578,    0x0012}, {0x8579,    0x0004}, {0x857a,    0x0001},
-{0x857b,    0x0001}, {0x857c,    0x0001}, {0x857d,    0x0001},
-{0x857e,    0x0001}, {0x857f,    0x0001}, {0x8580,    0x00b6},
-{0x8581,    0x0012}, {0x8582,    0x0004}, {0x8583,    0x0084},
-{0x8584,    0x00fe}, {0x8585,    0x008a}, {0x8586,    0x0002},
-{0x8587,    0x00b7}, {0x8588,    0x0012}, {0x8589,    0x0004},
-{0x858a,    0x0001}, {0x858b,    0x0001}, {0x858c,    0x0001},
-{0x858d,    0x0001}, {0x858e,    0x0001}, {0x858f,    0x0001},
-{0x8590,    0x0086}, {0x8591,    0x00fd}, {0x8592,    0x00b4},
-{0x8593,    0x0012}, {0x8594,    0x0004}, {0x8595,    0x00b7},
-{0x8596,    0x0012}, {0x8597,    0x0004}, {0x8598,    0x00b6},
-{0x8599,    0x0012}, {0x859a,    0x0000}, {0x859b,    0x0084},
-{0x859c,    0x0008}, {0x859d,    0x0081}, {0x859e,    0x0008},
-{0x859f,    0x0027}, {0x85a0,    0x0016}, {0x85a1,    0x00b6},
-{0x85a2,    0x008f}, {0x85a3,    0x007d}, {0x85a4,    0x0081},
-{0x85a5,    0x000c}, {0x85a6,    0x0027}, {0x85a7,    0x0008},
-{0x85a8,    0x008b}, {0x85a9,    0x0004}, {0x85aa,    0x00b7},
-{0x85ab,    0x008f}, {0x85ac,    0x007d}, {0x85ad,    0x007e},
-{0x85ae,    0x0085}, {0x85af,    0x006c}, {0x85b0,    0x0086},
-{0x85b1,    0x0003}, {0x85b2,    0x0097}, {0x85b3,    0x0040},
-{0x85b4,    0x007e}, {0x85b5,    0x0089}, {0x85b6,    0x006e},
-{0x85b7,    0x0086}, {0x85b8,    0x0007}, {0x85b9,    0x00b7},
-{0x85ba,    0x0012}, {0x85bb,    0x0006}, {0x85bc,    0x005f},
-{0x85bd,    0x00f7}, {0x85be,    0x008f}, {0x85bf,    0x0082},
-{0x85c0,    0x005f}, {0x85c1,    0x00f7}, {0x85c2,    0x008f},
-{0x85c3,    0x007f}, {0x85c4,    0x00f7}, {0x85c5,    0x008f},
-{0x85c6,    0x0070}, {0x85c7,    0x00f7}, {0x85c8,    0x008f},
-{0x85c9,    0x0071}, {0x85ca,    0x00f7}, {0x85cb,    0x008f},
-{0x85cc,    0x0072}, {0x85cd,    0x00f7}, {0x85ce,    0x008f},
-{0x85cf,    0x0073}, {0x85d0,    0x00f7}, {0x85d1,    0x008f},
-{0x85d2,    0x0074}, {0x85d3,    0x00f7}, {0x85d4,    0x008f},
-{0x85d5,    0x0075}, {0x85d6,    0x00f7}, {0x85d7,    0x008f},
-{0x85d8,    0x0076}, {0x85d9,    0x00f7}, {0x85da,    0x008f},
-{0x85db,    0x0077}, {0x85dc,    0x00f7}, {0x85dd,    0x008f},
-{0x85de,    0x0078}, {0x85df,    0x00f7}, {0x85e0,    0x008f},
-{0x85e1,    0x0079}, {0x85e2,    0x00f7}, {0x85e3,    0x008f},
-{0x85e4,    0x007a}, {0x85e5,    0x00f7}, {0x85e6,    0x008f},
-{0x85e7,    0x007b}, {0x85e8,    0x00b6}, {0x85e9,    0x0012},
-{0x85ea,    0x0004}, {0x85eb,    0x008a}, {0x85ec,    0x0010},
-{0x85ed,    0x00b7}, {0x85ee,    0x0012}, {0x85ef,    0x0004},
-{0x85f0,    0x0086}, {0x85f1,    0x00e4}, {0x85f2,    0x00b7},
-{0x85f3,    0x0012}, {0x85f4,    0x0070}, {0x85f5,    0x00b7},
-{0x85f6,    0x0012}, {0x85f7,    0x0007}, {0x85f8,    0x00f7},
-{0x85f9,    0x0012}, {0x85fa,    0x0005}, {0x85fb,    0x00f7},
-{0x85fc,    0x0012}, {0x85fd,    0x0009}, {0x85fe,    0x0086},
-{0x85ff,    0x0008}, {0x8600,    0x00ba}, {0x8601,    0x0012},
-{0x8602,    0x0004}, {0x8603,    0x00b7}, {0x8604,    0x0012},
-{0x8605,    0x0004}, {0x8606,    0x0086}, {0x8607,    0x00f7},
-{0x8608,    0x00b4}, {0x8609,    0x0012}, {0x860a,    0x0004},
-{0x860b,    0x00b7}, {0x860c,    0x0012}, {0x860d,    0x0004},
-{0x860e,    0x0001}, {0x860f,    0x0001}, {0x8610,    0x0001},
-{0x8611,    0x0001}, {0x8612,    0x0001}, {0x8613,    0x0001},
-{0x8614,    0x00b6}, {0x8615,    0x0012}, {0x8616,    0x0008},
-{0x8617,    0x0027}, {0x8618,    0x007f}, {0x8619,    0x0081},
-{0x861a,    0x0080}, {0x861b,    0x0026}, {0x861c,    0x000b},
-{0x861d,    0x0086}, {0x861e,    0x0008}, {0x861f,    0x00ce},
-{0x8620,    0x008f}, {0x8621,    0x0079}, {0x8622,    0x00bd},
-{0x8623,    0x0089}, {0x8624,    0x007b}, {0x8625,    0x007e},
-{0x8626,    0x0086}, {0x8627,    0x008e}, {0x8628,    0x0081},
-{0x8629,    0x0040}, {0x862a,    0x0026}, {0x862b,    0x000b},
-{0x862c,    0x0086}, {0x862d,    0x0004}, {0x862e,    0x00ce},
-{0x862f,    0x008f}, {0x8630,    0x0076}, {0x8631,    0x00bd},
-{0x8632,    0x0089}, {0x8633,    0x007b}, {0x8634,    0x007e},
-{0x8635,    0x0086}, {0x8636,    0x008e}, {0x8637,    0x0081},
-{0x8638,    0x0020}, {0x8639,    0x0026}, {0x863a,    0x000b},
-{0x863b,    0x0086}, {0x863c,    0x0002}, {0x863d,    0x00ce},
-{0x863e,    0x008f}, {0x863f,    0x0073}, {0x8640,    0x00bd},
-{0x8641,    0x0089}, {0x8642,    0x007b}, {0x8643,    0x007e},
-{0x8644,    0x0086}, {0x8645,    0x008e}, {0x8646,    0x0081},
-{0x8647,    0x0010}, {0x8648,    0x0026}, {0x8649,    0x000b},
-{0x864a,    0x0086}, {0x864b,    0x0001}, {0x864c,    0x00ce},
-{0x864d,    0x008f}, {0x864e,    0x0070}, {0x864f,    0x00bd},
-{0x8650,    0x0089}, {0x8651,    0x007b}, {0x8652,    0x007e},
-{0x8653,    0x0086}, {0x8654,    0x008e}, {0x8655,    0x0081},
-{0x8656,    0x0008}, {0x8657,    0x0026}, {0x8658,    0x000b},
-{0x8659,    0x0086}, {0x865a,    0x0008}, {0x865b,    0x00ce},
-{0x865c,    0x008f}, {0x865d,    0x0079}, {0x865e,    0x00bd},
-{0x865f,    0x0089}, {0x8660,    0x007f}, {0x8661,    0x007e},
-{0x8662,    0x0086}, {0x8663,    0x008e}, {0x8664,    0x0081},
-{0x8665,    0x0004}, {0x8666,    0x0026}, {0x8667,    0x000b},
-{0x8668,    0x0086}, {0x8669,    0x0004}, {0x866a,    0x00ce},
-{0x866b,    0x008f}, {0x866c,    0x0076}, {0x866d,    0x00bd},
-{0x866e,    0x0089}, {0x866f,    0x007f}, {0x8670,    0x007e},
-{0x8671,    0x0086}, {0x8672,    0x008e}, {0x8673,    0x0081},
-{0x8674,    0x0002}, {0x8675,    0x0026}, {0x8676,    0x000b},
-{0x8677,    0x008a}, {0x8678,    0x0002}, {0x8679,    0x00ce},
-{0x867a,    0x008f}, {0x867b,    0x0073}, {0x867c,    0x00bd},
-{0x867d,    0x0089}, {0x867e,    0x007f}, {0x867f,    0x007e},
-{0x8680,    0x0086}, {0x8681,    0x008e}, {0x8682,    0x0081},
-{0x8683,    0x0001}, {0x8684,    0x0026}, {0x8685,    0x0008},
-{0x8686,    0x0086}, {0x8687,    0x0001}, {0x8688,    0x00ce},
-{0x8689,    0x008f}, {0x868a,    0x0070}, {0x868b,    0x00bd},
-{0x868c,    0x0089}, {0x868d,    0x007f}, {0x868e,    0x00b6},
-{0x868f,    0x008f}, {0x8690,    0x007f}, {0x8691,    0x0081},
-{0x8692,    0x000f}, {0x8693,    0x0026}, {0x8694,    0x0003},
-{0x8695,    0x007e}, {0x8696,    0x0087}, {0x8697,    0x0047},
-{0x8698,    0x00b6}, {0x8699,    0x0012}, {0x869a,    0x0009},
-{0x869b,    0x0084}, {0x869c,    0x0003}, {0x869d,    0x0081},
-{0x869e,    0x0003}, {0x869f,    0x0027}, {0x86a0,    0x0006},
-{0x86a1,    0x007c}, {0x86a2,    0x0012}, {0x86a3,    0x0009},
-{0x86a4,    0x007e}, {0x86a5,    0x0085}, {0x86a6,    0x00fe},
-{0x86a7,    0x00b6}, {0x86a8,    0x0012}, {0x86a9,    0x0006},
-{0x86aa,    0x0084}, {0x86ab,    0x0007}, {0x86ac,    0x0081},
-{0x86ad,    0x0007}, {0x86ae,    0x0027}, {0x86af,    0x0008},
-{0x86b0,    0x008b}, {0x86b1,    0x0001}, {0x86b2,    0x00b7},
-{0x86b3,    0x0012}, {0x86b4,    0x0006}, {0x86b5,    0x007e},
-{0x86b6,    0x0086}, {0x86b7,    0x00d5}, {0x86b8,    0x00b6},
-{0x86b9,    0x008f}, {0x86ba,    0x0082}, {0x86bb,    0x0026},
-{0x86bc,    0x000a}, {0x86bd,    0x007c}, {0x86be,    0x008f},
-{0x86bf,    0x0082}, {0x86c0,    0x004f}, {0x86c1,    0x00b7},
-{0x86c2,    0x0012}, {0x86c3,    0x0006}, {0x86c4,    0x007e},
-{0x86c5,    0x0085}, {0x86c6,    0x00c0}, {0x86c7,    0x00b6},
-{0x86c8,    0x0012}, {0x86c9,    0x0006}, {0x86ca,    0x0084},
-{0x86cb,    0x003f}, {0x86cc,    0x0081}, {0x86cd,    0x003f},
-{0x86ce,    0x0027}, {0x86cf,    0x0010}, {0x86d0,    0x008b},
-{0x86d1,    0x0008}, {0x86d2,    0x00b7}, {0x86d3,    0x0012},
-{0x86d4,    0x0006}, {0x86d5,    0x00b6}, {0x86d6,    0x0012},
-{0x86d7,    0x0009}, {0x86d8,    0x0084}, {0x86d9,    0x00fc},
-{0x86da,    0x00b7}, {0x86db,    0x0012}, {0x86dc,    0x0009},
-{0x86dd,    0x007e}, {0x86de,    0x0085}, {0x86df,    0x00fe},
-{0x86e0,    0x00ce}, {0x86e1,    0x008f}, {0x86e2,    0x0070},
-{0x86e3,    0x0018}, {0x86e4,    0x00ce}, {0x86e5,    0x008f},
-{0x86e6,    0x0084}, {0x86e7,    0x00c6}, {0x86e8,    0x000c},
-{0x86e9,    0x00bd}, {0x86ea,    0x0089}, {0x86eb,    0x006f},
-{0x86ec,    0x00ce}, {0x86ed,    0x008f}, {0x86ee,    0x0084},
-{0x86ef,    0x0018}, {0x86f0,    0x00ce}, {0x86f1,    0x008f},
-{0x86f2,    0x0070}, {0x86f3,    0x00c6}, {0x86f4,    0x000c},
-{0x86f5,    0x00bd}, {0x86f6,    0x0089}, {0x86f7,    0x006f},
-{0x86f8,    0x00d6}, {0x86f9,    0x0083}, {0x86fa,    0x00c1},
-{0x86fb,    0x004f}, {0x86fc,    0x002d}, {0x86fd,    0x0003},
-{0x86fe,    0x007e}, {0x86ff,    0x0087}, {0x8700,    0x0040},
-{0x8701,    0x00b6}, {0x8702,    0x008f}, {0x8703,    0x007f},
-{0x8704,    0x0081}, {0x8705,    0x0007}, {0x8706,    0x0027},
-{0x8707,    0x000f}, {0x8708,    0x0081}, {0x8709,    0x000b},
-{0x870a,    0x0027}, {0x870b,    0x0015}, {0x870c,    0x0081},
-{0x870d,    0x000d}, {0x870e,    0x0027}, {0x870f,    0x001b},
-{0x8710,    0x0081}, {0x8711,    0x000e}, {0x8712,    0x0027},
-{0x8713,    0x0021}, {0x8714,    0x007e}, {0x8715,    0x0087},
-{0x8716,    0x0040}, {0x8717,    0x00f7}, {0x8718,    0x008f},
-{0x8719,    0x007b}, {0x871a,    0x0086}, {0x871b,    0x0002},
-{0x871c,    0x00b7}, {0x871d,    0x008f}, {0x871e,    0x007a},
-{0x871f,    0x0020}, {0x8720,    0x001c}, {0x8721,    0x00f7},
-{0x8722,    0x008f}, {0x8723,    0x0078}, {0x8724,    0x0086},
-{0x8725,    0x0002}, {0x8726,    0x00b7}, {0x8727,    0x008f},
-{0x8728,    0x0077}, {0x8729,    0x0020}, {0x872a,    0x0012},
-{0x872b,    0x00f7}, {0x872c,    0x008f}, {0x872d,    0x0075},
-{0x872e,    0x0086}, {0x872f,    0x0002}, {0x8730,    0x00b7},
-{0x8731,    0x008f}, {0x8732,    0x0074}, {0x8733,    0x0020},
-{0x8734,    0x0008}, {0x8735,    0x00f7}, {0x8736,    0x008f},
-{0x8737,    0x0072}, {0x8738,    0x0086}, {0x8739,    0x0002},
-{0x873a,    0x00b7}, {0x873b,    0x008f}, {0x873c,    0x0071},
-{0x873d,    0x007e}, {0x873e,    0x0087}, {0x873f,    0x0047},
-{0x8740,    0x0086}, {0x8741,    0x0004}, {0x8742,    0x0097},
-{0x8743,    0x0040}, {0x8744,    0x007e}, {0x8745,    0x0089},
-{0x8746,    0x006e}, {0x8747,    0x00ce}, {0x8748,    0x008f},
-{0x8749,    0x0072}, {0x874a,    0x00bd}, {0x874b,    0x0089},
-{0x874c,    0x00f7}, {0x874d,    0x00ce}, {0x874e,    0x008f},
-{0x874f,    0x0075}, {0x8750,    0x00bd}, {0x8751,    0x0089},
-{0x8752,    0x00f7}, {0x8753,    0x00ce}, {0x8754,    0x008f},
-{0x8755,    0x0078}, {0x8756,    0x00bd}, {0x8757,    0x0089},
-{0x8758,    0x00f7}, {0x8759,    0x00ce}, {0x875a,    0x008f},
-{0x875b,    0x007b}, {0x875c,    0x00bd}, {0x875d,    0x0089},
-{0x875e,    0x00f7}, {0x875f,    0x004f}, {0x8760,    0x00b7},
-{0x8761,    0x008f}, {0x8762,    0x007d}, {0x8763,    0x00b7},
-{0x8764,    0x008f}, {0x8765,    0x0081}, {0x8766,    0x00b6},
-{0x8767,    0x008f}, {0x8768,    0x0072}, {0x8769,    0x0027},
-{0x876a,    0x0047}, {0x876b,    0x007c}, {0x876c,    0x008f},
-{0x876d,    0x007d}, {0x876e,    0x00b6}, {0x876f,    0x008f},
-{0x8770,    0x0075}, {0x8771,    0x0027}, {0x8772,    0x003f},
-{0x8773,    0x007c}, {0x8774,    0x008f}, {0x8775,    0x007d},
-{0x8776,    0x00b6}, {0x8777,    0x008f}, {0x8778,    0x0078},
-{0x8779,    0x0027}, {0x877a,    0x0037}, {0x877b,    0x007c},
-{0x877c,    0x008f}, {0x877d,    0x007d}, {0x877e,    0x00b6},
-{0x877f,    0x008f}, {0x8780,    0x007b}, {0x8781,    0x0027},
-{0x8782,    0x002f}, {0x8783,    0x007f}, {0x8784,    0x008f},
-{0x8785,    0x007d}, {0x8786,    0x007c}, {0x8787,    0x008f},
-{0x8788,    0x0081}, {0x8789,    0x007a}, {0x878a,    0x008f},
-{0x878b,    0x0072}, {0x878c,    0x0027}, {0x878d,    0x001b},
-{0x878e,    0x007c}, {0x878f,    0x008f}, {0x8790,    0x007d},
-{0x8791,    0x007a}, {0x8792,    0x008f}, {0x8793,    0x0075},
-{0x8794,    0x0027}, {0x8795,    0x0016}, {0x8796,    0x007c},
-{0x8797,    0x008f}, {0x8798,    0x007d}, {0x8799,    0x007a},
-{0x879a,    0x008f}, {0x879b,    0x0078}, {0x879c,    0x0027},
-{0x879d,    0x0011}, {0x879e,    0x007c}, {0x879f,    0x008f},
-{0x87a0,    0x007d}, {0x87a1,    0x007a}, {0x87a2,    0x008f},
-{0x87a3,    0x007b}, {0x87a4,    0x0027}, {0x87a5,    0x000c},
-{0x87a6,    0x007e}, {0x87a7,    0x0087}, {0x87a8,    0x0083},
-{0x87a9,    0x007a}, {0x87aa,    0x008f}, {0x87ab,    0x0075},
-{0x87ac,    0x007a}, {0x87ad,    0x008f}, {0x87ae,    0x0078},
-{0x87af,    0x007a}, {0x87b0,    0x008f}, {0x87b1,    0x007b},
-{0x87b2,    0x00ce}, {0x87b3,    0x00c1}, {0x87b4,    0x00fc},
-{0x87b5,    0x00f6}, {0x87b6,    0x008f}, {0x87b7,    0x007d},
-{0x87b8,    0x003a}, {0x87b9,    0x00a6}, {0x87ba,    0x0000},
-{0x87bb,    0x00b7}, {0x87bc,    0x0012}, {0x87bd,    0x0070},
-{0x87be,    0x00b6}, {0x87bf,    0x008f}, {0x87c0,    0x0072},
-{0x87c1,    0x0026}, {0x87c2,    0x0003}, {0x87c3,    0x007e},
-{0x87c4,    0x0087}, {0x87c5,    0x00fa}, {0x87c6,    0x00b6},
-{0x87c7,    0x008f}, {0x87c8,    0x0075}, {0x87c9,    0x0026},
-{0x87ca,    0x000a}, {0x87cb,    0x0018}, {0x87cc,    0x00ce},
-{0x87cd,    0x008f}, {0x87ce,    0x0073}, {0x87cf,    0x00bd},
-{0x87d0,    0x0089}, {0x87d1,    0x00d5}, {0x87d2,    0x007e},
-{0x87d3,    0x0087}, {0x87d4,    0x00fa}, {0x87d5,    0x00b6},
-{0x87d6,    0x008f}, {0x87d7,    0x0078}, {0x87d8,    0x0026},
-{0x87d9,    0x000a}, {0x87da,    0x0018}, {0x87db,    0x00ce},
-{0x87dc,    0x008f}, {0x87dd,    0x0076}, {0x87de,    0x00bd},
-{0x87df,    0x0089}, {0x87e0,    0x00d5}, {0x87e1,    0x007e},
-{0x87e2,    0x0087}, {0x87e3,    0x00fa}, {0x87e4,    0x00b6},
-{0x87e5,    0x008f}, {0x87e6,    0x007b}, {0x87e7,    0x0026},
-{0x87e8,    0x000a}, {0x87e9,    0x0018}, {0x87ea,    0x00ce},
-{0x87eb,    0x008f}, {0x87ec,    0x0079}, {0x87ed,    0x00bd},
-{0x87ee,    0x0089}, {0x87ef,    0x00d5}, {0x87f0,    0x007e},
-{0x87f1,    0x0087}, {0x87f2,    0x00fa}, {0x87f3,    0x0086},
-{0x87f4,    0x0005}, {0x87f5,    0x0097}, {0x87f6,    0x0040},
-{0x87f7,    0x007e}, {0x87f8,    0x0089}, {0x87f9,    0x006e},
-{0x87fa,    0x00b6}, {0x87fb,    0x008f}, {0x87fc,    0x0075},
-{0x87fd,    0x0081}, {0x87fe,    0x0007}, {0x87ff,    0x002e},
-{0x8800,    0x00f2}, {0x8801,    0x00f6}, {0x8802,    0x0012},
-{0x8803,    0x0006}, {0x8804,    0x00c4}, {0x8805,    0x00f8},
-{0x8806,    0x001b}, {0x8807,    0x00b7}, {0x8808,    0x0012},
-{0x8809,    0x0006}, {0x880a,    0x00b6}, {0x880b,    0x008f},
-{0x880c,    0x0078}, {0x880d,    0x0081}, {0x880e,    0x0007},
-{0x880f,    0x002e}, {0x8810,    0x00e2}, {0x8811,    0x0048},
-{0x8812,    0x0048}, {0x8813,    0x0048}, {0x8814,    0x00f6},
-{0x8815,    0x0012}, {0x8816,    0x0006}, {0x8817,    0x00c4},
-{0x8818,    0x00c7}, {0x8819,    0x001b}, {0x881a,    0x00b7},
-{0x881b,    0x0012}, {0x881c,    0x0006}, {0x881d,    0x00b6},
-{0x881e,    0x008f}, {0x881f,    0x007b}, {0x8820,    0x0081},
-{0x8821,    0x0007}, {0x8822,    0x002e}, {0x8823,    0x00cf},
-{0x8824,    0x00f6}, {0x8825,    0x0012}, {0x8826,    0x0005},
-{0x8827,    0x00c4}, {0x8828,    0x00f8}, {0x8829,    0x001b},
-{0x882a,    0x00b7}, {0x882b,    0x0012}, {0x882c,    0x0005},
-{0x882d,    0x0086}, {0x882e,    0x0000}, {0x882f,    0x00f6},
-{0x8830,    0x008f}, {0x8831,    0x0071}, {0x8832,    0x00bd},
-{0x8833,    0x0089}, {0x8834,    0x0094}, {0x8835,    0x0086},
-{0x8836,    0x0001}, {0x8837,    0x00f6}, {0x8838,    0x008f},
-{0x8839,    0x0074}, {0x883a,    0x00bd}, {0x883b,    0x0089},
-{0x883c,    0x0094}, {0x883d,    0x0086}, {0x883e,    0x0002},
-{0x883f,    0x00f6}, {0x8840,    0x008f}, {0x8841,    0x0077},
-{0x8842,    0x00bd}, {0x8843,    0x0089}, {0x8844,    0x0094},
-{0x8845,    0x0086}, {0x8846,    0x0003}, {0x8847,    0x00f6},
-{0x8848,    0x008f}, {0x8849,    0x007a}, {0x884a,    0x00bd},
-{0x884b,    0x0089}, {0x884c,    0x0094}, {0x884d,    0x00ce},
-{0x884e,    0x008f}, {0x884f,    0x0070}, {0x8850,    0x00a6},
-{0x8851,    0x0001}, {0x8852,    0x0081}, {0x8853,    0x0001},
-{0x8854,    0x0027}, {0x8855,    0x0007}, {0x8856,    0x0081},
-{0x8857,    0x0003}, {0x8858,    0x0027}, {0x8859,    0x0003},
-{0x885a,    0x007e}, {0x885b,    0x0088}, {0x885c,    0x0066},
-{0x885d,    0x00a6}, {0x885e,    0x0000}, {0x885f,    0x00b8},
-{0x8860,    0x008f}, {0x8861,    0x0081}, {0x8862,    0x0084},
-{0x8863,    0x0001}, {0x8864,    0x0026}, {0x8865,    0x000b},
-{0x8866,    0x008c}, {0x8867,    0x008f}, {0x8868,    0x0079},
-{0x8869,    0x002c}, {0x886a,    0x000e}, {0x886b,    0x0008},
-{0x886c,    0x0008}, {0x886d,    0x0008}, {0x886e,    0x007e},
-{0x886f,    0x0088}, {0x8870,    0x0050}, {0x8871,    0x00b6},
-{0x8872,    0x0012}, {0x8873,    0x0004}, {0x8874,    0x008a},
-{0x8875,    0x0040}, {0x8876,    0x00b7}, {0x8877,    0x0012},
-{0x8878,    0x0004}, {0x8879,    0x00b6}, {0x887a,    0x0012},
-{0x887b,    0x0004}, {0x887c,    0x0084}, {0x887d,    0x00fb},
-{0x887e,    0x0084}, {0x887f,    0x00ef}, {0x8880,    0x00b7},
-{0x8881,    0x0012}, {0x8882,    0x0004}, {0x8883,    0x00b6},
-{0x8884,    0x0012}, {0x8885,    0x0007}, {0x8886,    0x0036},
-{0x8887,    0x00b6}, {0x8888,    0x008f}, {0x8889,    0x007c},
-{0x888a,    0x0048}, {0x888b,    0x0048}, {0x888c,    0x00b7},
-{0x888d,    0x0012}, {0x888e,    0x0007}, {0x888f,    0x0086},
-{0x8890,    0x0001}, {0x8891,    0x00ba}, {0x8892,    0x0012},
-{0x8893,    0x0004}, {0x8894,    0x00b7}, {0x8895,    0x0012},
-{0x8896,    0x0004}, {0x8897,    0x0001}, {0x8898,    0x0001},
-{0x8899,    0x0001}, {0x889a,    0x0001}, {0x889b,    0x0001},
-{0x889c,    0x0001}, {0x889d,    0x0086}, {0x889e,    0x00fe},
-{0x889f,    0x00b4}, {0x88a0,    0x0012}, {0x88a1,    0x0004},
-{0x88a2,    0x00b7}, {0x88a3,    0x0012}, {0x88a4,    0x0004},
-{0x88a5,    0x0086}, {0x88a6,    0x0002}, {0x88a7,    0x00ba},
-{0x88a8,    0x0012}, {0x88a9,    0x0004}, {0x88aa,    0x00b7},
-{0x88ab,    0x0012}, {0x88ac,    0x0004}, {0x88ad,    0x0086},
-{0x88ae,    0x00fd}, {0x88af,    0x00b4}, {0x88b0,    0x0012},
-{0x88b1,    0x0004}, {0x88b2,    0x00b7}, {0x88b3,    0x0012},
-{0x88b4,    0x0004}, {0x88b5,    0x0032}, {0x88b6,    0x00b7},
-{0x88b7,    0x0012}, {0x88b8,    0x0007}, {0x88b9,    0x00b6},
-{0x88ba,    0x0012}, {0x88bb,    0x0000}, {0x88bc,    0x0084},
-{0x88bd,    0x0008}, {0x88be,    0x0081}, {0x88bf,    0x0008},
-{0x88c0,    0x0027}, {0x88c1,    0x000f}, {0x88c2,    0x007c},
-{0x88c3,    0x0082}, {0x88c4,    0x0008}, {0x88c5,    0x0026},
-{0x88c6,    0x0007}, {0x88c7,    0x0086}, {0x88c8,    0x0076},
-{0x88c9,    0x0097}, {0x88ca,    0x0040}, {0x88cb,    0x007e},
-{0x88cc,    0x0089}, {0x88cd,    0x006e}, {0x88ce,    0x007e},
-{0x88cf,    0x0086}, {0x88d0,    0x00ec}, {0x88d1,    0x00b6},
-{0x88d2,    0x008f}, {0x88d3,    0x007f}, {0x88d4,    0x0081},
-{0x88d5,    0x000f}, {0x88d6,    0x0027}, {0x88d7,    0x003c},
-{0x88d8,    0x00bd}, {0x88d9,    0x00e6}, {0x88da,    0x00c7},
-{0x88db,    0x00b7}, {0x88dc,    0x0012}, {0x88dd,    0x000d},
-{0x88de,    0x00bd}, {0x88df,    0x00e6}, {0x88e0,    0x00cb},
-{0x88e1,    0x00b6}, {0x88e2,    0x0012}, {0x88e3,    0x0004},
-{0x88e4,    0x008a}, {0x88e5,    0x0020}, {0x88e6,    0x00b7},
-{0x88e7,    0x0012}, {0x88e8,    0x0004}, {0x88e9,    0x00ce},
-{0x88ea,    0x00ff}, {0x88eb,    0x00ff}, {0x88ec,    0x00b6},
-{0x88ed,    0x0012}, {0x88ee,    0x0000}, {0x88ef,    0x0081},
-{0x88f0,    0x000c}, {0x88f1,    0x0026}, {0x88f2,    0x0005},
-{0x88f3,    0x0009}, {0x88f4,    0x0026}, {0x88f5,    0x00f6},
-{0x88f6,    0x0027}, {0x88f7,    0x001c}, {0x88f8,    0x00b6},
-{0x88f9,    0x0012}, {0x88fa,    0x0004}, {0x88fb,    0x0084},
-{0x88fc,    0x00df}, {0x88fd,    0x00b7}, {0x88fe,    0x0012},
-{0x88ff,    0x0004}, {0x8900,    0x0096}, {0x8901,    0x0083},
-{0x8902,    0x0081}, {0x8903,    0x0007}, {0x8904,    0x002c},
-{0x8905,    0x0005}, {0x8906,    0x007c}, {0x8907,    0x0000},
-{0x8908,    0x0083}, {0x8909,    0x0020}, {0x890a,    0x0006},
-{0x890b,    0x0096}, {0x890c,    0x0083}, {0x890d,    0x008b},
-{0x890e,    0x0008}, {0x890f,    0x0097}, {0x8910,    0x0083},
-{0x8911,    0x007e}, {0x8912,    0x0085}, {0x8913,    0x0041},
-{0x8914,    0x007f}, {0x8915,    0x008f}, {0x8916,    0x007e},
-{0x8917,    0x0086}, {0x8918,    0x0080}, {0x8919,    0x00b7},
-{0x891a,    0x0012}, {0x891b,    0x000c}, {0x891c,    0x0086},
-{0x891d,    0x0001}, {0x891e,    0x00b7}, {0x891f,    0x008f},
-{0x8920,    0x007d}, {0x8921,    0x00b6}, {0x8922,    0x0012},
-{0x8923,    0x000c}, {0x8924,    0x0084}, {0x8925,    0x007f},
-{0x8926,    0x00b7}, {0x8927,    0x0012}, {0x8928,    0x000c},
-{0x8929,    0x008a}, {0x892a,    0x0080}, {0x892b,    0x00b7},
-{0x892c,    0x0012}, {0x892d,    0x000c}, {0x892e,    0x0086},
-{0x892f,    0x000a}, {0x8930,    0x00bd}, {0x8931,    0x008a},
-{0x8932,    0x0006}, {0x8933,    0x00b6}, {0x8934,    0x0012},
-{0x8935,    0x000a}, {0x8936,    0x002a}, {0x8937,    0x0009},
-{0x8938,    0x00b6}, {0x8939,    0x0012}, {0x893a,    0x000c},
-{0x893b,    0x00ba}, {0x893c,    0x008f}, {0x893d,    0x007d},
-{0x893e,    0x00b7}, {0x893f,    0x0012}, {0x8940,    0x000c},
-{0x8941,    0x00b6}, {0x8942,    0x008f}, {0x8943,    0x007e},
-{0x8944,    0x0081}, {0x8945,    0x0060}, {0x8946,    0x0027},
-{0x8947,    0x001a}, {0x8948,    0x008b}, {0x8949,    0x0020},
-{0x894a,    0x00b7}, {0x894b,    0x008f}, {0x894c,    0x007e},
-{0x894d,    0x00b6}, {0x894e,    0x0012}, {0x894f,    0x000c},
-{0x8950,    0x0084}, {0x8951,    0x009f}, {0x8952,    0x00ba},
-{0x8953,    0x008f}, {0x8954,    0x007e}, {0x8955,    0x00b7},
-{0x8956,    0x0012}, {0x8957,    0x000c}, {0x8958,    0x00b6},
-{0x8959,    0x008f}, {0x895a,    0x007d}, {0x895b,    0x0048},
-{0x895c,    0x00b7}, {0x895d,    0x008f}, {0x895e,    0x007d},
-{0x895f,    0x007e}, {0x8960,    0x0089}, {0x8961,    0x0021},
-{0x8962,    0x00b6}, {0x8963,    0x0012}, {0x8964,    0x0004},
-{0x8965,    0x008a}, {0x8966,    0x0020}, {0x8967,    0x00b7},
-{0x8968,    0x0012}, {0x8969,    0x0004}, {0x896a,    0x00bd},
-{0x896b,    0x008a}, {0x896c,    0x000a}, {0x896d,    0x004f},
-{0x896e,    0x0039}, {0x896f,    0x00a6}, {0x8970,    0x0000},
-{0x8971,    0x0018}, {0x8972,    0x00a7}, {0x8973,    0x0000},
-{0x8974,    0x0008}, {0x8975,    0x0018}, {0x8976,    0x0008},
-{0x8977,    0x005a}, {0x8978,    0x0026}, {0x8979,    0x00f5},
-{0x897a,    0x0039}, {0x897b,    0x0036}, {0x897c,    0x006c},
-{0x897d,    0x0000}, {0x897e,    0x0032}, {0x897f,    0x00ba},
-{0x8980,    0x008f}, {0x8981,    0x007f}, {0x8982,    0x00b7},
-{0x8983,    0x008f}, {0x8984,    0x007f}, {0x8985,    0x00b6},
-{0x8986,    0x0012}, {0x8987,    0x0009}, {0x8988,    0x0084},
-{0x8989,    0x0003}, {0x898a,    0x00a7}, {0x898b,    0x0001},
-{0x898c,    0x00b6}, {0x898d,    0x0012}, {0x898e,    0x0006},
-{0x898f,    0x0084}, {0x8990,    0x003f}, {0x8991,    0x00a7},
-{0x8992,    0x0002}, {0x8993,    0x0039}, {0x8994,    0x0036},
-{0x8995,    0x0086}, {0x8996,    0x0003}, {0x8997,    0x00b7},
-{0x8998,    0x008f}, {0x8999,    0x0080}, {0x899a,    0x0032},
-{0x899b,    0x00c1}, {0x899c,    0x0000}, {0x899d,    0x0026},
-{0x899e,    0x0006}, {0x899f,    0x00b7}, {0x89a0,    0x008f},
-{0x89a1,    0x007c}, {0x89a2,    0x007e}, {0x89a3,    0x0089},
-{0x89a4,    0x00c9}, {0x89a5,    0x00c1}, {0x89a6,    0x0001},
-{0x89a7,    0x0027}, {0x89a8,    0x0018}, {0x89a9,    0x00c1},
-{0x89aa,    0x0002}, {0x89ab,    0x0027}, {0x89ac,    0x000c},
-{0x89ad,    0x00c1}, {0x89ae,    0x0003}, {0x89af,    0x0027},
-{0x89b0,    0x0000}, {0x89b1,    0x00f6}, {0x89b2,    0x008f},
-{0x89b3,    0x0080}, {0x89b4,    0x0005}, {0x89b5,    0x0005},
-{0x89b6,    0x00f7}, {0x89b7,    0x008f}, {0x89b8,    0x0080},
-{0x89b9,    0x00f6}, {0x89ba,    0x008f}, {0x89bb,    0x0080},
-{0x89bc,    0x0005}, {0x89bd,    0x0005}, {0x89be,    0x00f7},
-{0x89bf,    0x008f}, {0x89c0,    0x0080}, {0x89c1,    0x00f6},
-{0x89c2,    0x008f}, {0x89c3,    0x0080}, {0x89c4,    0x0005},
-{0x89c5,    0x0005}, {0x89c6,    0x00f7}, {0x89c7,    0x008f},
-{0x89c8,    0x0080}, {0x89c9,    0x00f6}, {0x89ca,    0x008f},
-{0x89cb,    0x0080}, {0x89cc,    0x0053}, {0x89cd,    0x00f4},
-{0x89ce,    0x0012}, {0x89cf,    0x0007}, {0x89d0,    0x001b},
-{0x89d1,    0x00b7}, {0x89d2,    0x0012}, {0x89d3,    0x0007},
-{0x89d4,    0x0039}, {0x89d5,    0x00ce}, {0x89d6,    0x008f},
-{0x89d7,    0x0070}, {0x89d8,    0x00a6}, {0x89d9,    0x0000},
-{0x89da,    0x0018}, {0x89db,    0x00e6}, {0x89dc,    0x0000},
-{0x89dd,    0x0018}, {0x89de,    0x00a7}, {0x89df,    0x0000},
-{0x89e0,    0x00e7}, {0x89e1,    0x0000}, {0x89e2,    0x00a6},
-{0x89e3,    0x0001}, {0x89e4,    0x0018}, {0x89e5,    0x00e6},
-{0x89e6,    0x0001}, {0x89e7,    0x0018}, {0x89e8,    0x00a7},
-{0x89e9,    0x0001}, {0x89ea,    0x00e7}, {0x89eb,    0x0001},
-{0x89ec,    0x00a6}, {0x89ed,    0x0002}, {0x89ee,    0x0018},
-{0x89ef,    0x00e6}, {0x89f0,    0x0002}, {0x89f1,    0x0018},
-{0x89f2,    0x00a7}, {0x89f3,    0x0002}, {0x89f4,    0x00e7},
-{0x89f5,    0x0002}, {0x89f6,    0x0039}, {0x89f7,    0x00a6},
-{0x89f8,    0x0000}, {0x89f9,    0x0084}, {0x89fa,    0x0007},
-{0x89fb,    0x00e6}, {0x89fc,    0x0000}, {0x89fd,    0x00c4},
-{0x89fe,    0x0038}, {0x89ff,    0x0054}, {0x8a00,    0x0054},
-{0x8a01,    0x0054}, {0x8a02,    0x001b}, {0x8a03,    0x00a7},
-{0x8a04,    0x0000}, {0x8a05,    0x0039}, {0x8a06,    0x004a},
-{0x8a07,    0x0026}, {0x8a08,    0x00fd}, {0x8a09,    0x0039},
-{0x8a0a,    0x0096}, {0x8a0b,    0x0022}, {0x8a0c,    0x0084},
-{0x8a0d,    0x000f}, {0x8a0e,    0x0097}, {0x8a0f,    0x0022},
-{0x8a10,    0x0086}, {0x8a11,    0x0001}, {0x8a12,    0x00b7},
-{0x8a13,    0x008f}, {0x8a14,    0x0070}, {0x8a15,    0x00b6},
-{0x8a16,    0x0012}, {0x8a17,    0x0007}, {0x8a18,    0x00b7},
-{0x8a19,    0x008f}, {0x8a1a,    0x0071}, {0x8a1b,    0x00f6},
-{0x8a1c,    0x0012}, {0x8a1d,    0x000c}, {0x8a1e,    0x00c4},
-{0x8a1f,    0x000f}, {0x8a20,    0x00c8}, {0x8a21,    0x000f},
-{0x8a22,    0x00f7}, {0x8a23,    0x008f}, {0x8a24,    0x0072},
-{0x8a25,    0x00f6}, {0x8a26,    0x008f}, {0x8a27,    0x0072},
-{0x8a28,    0x00b6}, {0x8a29,    0x008f}, {0x8a2a,    0x0071},
-{0x8a2b,    0x0084}, {0x8a2c,    0x0003}, {0x8a2d,    0x0027},
-{0x8a2e,    0x0014}, {0x8a2f,    0x0081}, {0x8a30,    0x0001},
-{0x8a31,    0x0027}, {0x8a32,    0x001c}, {0x8a33,    0x0081},
-{0x8a34,    0x0002}, {0x8a35,    0x0027}, {0x8a36,    0x0024},
-{0x8a37,    0x00f4}, {0x8a38,    0x008f}, {0x8a39,    0x0070},
-{0x8a3a,    0x0027}, {0x8a3b,    0x002a}, {0x8a3c,    0x0096},
-{0x8a3d,    0x0022}, {0x8a3e,    0x008a}, {0x8a3f,    0x0080},
-{0x8a40,    0x007e}, {0x8a41,    0x008a}, {0x8a42,    0x0064},
-{0x8a43,    0x00f4}, {0x8a44,    0x008f}, {0x8a45,    0x0070},
-{0x8a46,    0x0027}, {0x8a47,    0x001e}, {0x8a48,    0x0096},
-{0x8a49,    0x0022}, {0x8a4a,    0x008a}, {0x8a4b,    0x0010},
-{0x8a4c,    0x007e}, {0x8a4d,    0x008a}, {0x8a4e,    0x0064},
-{0x8a4f,    0x00f4}, {0x8a50,    0x008f}, {0x8a51,    0x0070},
-{0x8a52,    0x0027}, {0x8a53,    0x0012}, {0x8a54,    0x0096},
-{0x8a55,    0x0022}, {0x8a56,    0x008a}, {0x8a57,    0x0020},
-{0x8a58,    0x007e}, {0x8a59,    0x008a}, {0x8a5a,    0x0064},
-{0x8a5b,    0x00f4}, {0x8a5c,    0x008f}, {0x8a5d,    0x0070},
-{0x8a5e,    0x0027}, {0x8a5f,    0x0006}, {0x8a60,    0x0096},
-{0x8a61,    0x0022}, {0x8a62,    0x008a}, {0x8a63,    0x0040},
-{0x8a64,    0x0097}, {0x8a65,    0x0022}, {0x8a66,    0x0074},
-{0x8a67,    0x008f}, {0x8a68,    0x0071}, {0x8a69,    0x0074},
-{0x8a6a,    0x008f}, {0x8a6b,    0x0071}, {0x8a6c,    0x0078},
-{0x8a6d,    0x008f}, {0x8a6e,    0x0070}, {0x8a6f,    0x00b6},
-{0x8a70,    0x008f}, {0x8a71,    0x0070}, {0x8a72,    0x0085},
-{0x8a73,    0x0010}, {0x8a74,    0x0027}, {0x8a75,    0x00af},
-{0x8a76,    0x00d6}, {0x8a77,    0x0022}, {0x8a78,    0x00c4},
-{0x8a79,    0x0010}, {0x8a7a,    0x0058}, {0x8a7b,    0x00b6},
-{0x8a7c,    0x0012}, {0x8a7d,    0x0070}, {0x8a7e,    0x0081},
-{0x8a7f,    0x00e4}, {0x8a80,    0x0027}, {0x8a81,    0x0036},
-{0x8a82,    0x0081}, {0x8a83,    0x00e1}, {0x8a84,    0x0026},
-{0x8a85,    0x000c}, {0x8a86,    0x0096}, {0x8a87,    0x0022},
-{0x8a88,    0x0084}, {0x8a89,    0x0020}, {0x8a8a,    0x0044},
-{0x8a8b,    0x001b}, {0x8a8c,    0x00d6}, {0x8a8d,    0x0022},
-{0x8a8e,    0x00c4}, {0x8a8f,    0x00cf}, {0x8a90,    0x0020},
-{0x8a91,    0x0023}, {0x8a92,    0x0058}, {0x8a93,    0x0081},
-{0x8a94,    0x00c6}, {0x8a95,    0x0026}, {0x8a96,    0x000d},
-{0x8a97,    0x0096}, {0x8a98,    0x0022}, {0x8a99,    0x0084},
-{0x8a9a,    0x0040}, {0x8a9b,    0x0044}, {0x8a9c,    0x0044},
-{0x8a9d,    0x001b}, {0x8a9e,    0x00d6}, {0x8a9f,    0x0022},
-{0x8aa0,    0x00c4}, {0x8aa1,    0x00af}, {0x8aa2,    0x0020},
-{0x8aa3,    0x0011}, {0x8aa4,    0x0058}, {0x8aa5,    0x0081},
-{0x8aa6,    0x0027}, {0x8aa7,    0x0026}, {0x8aa8,    0x000f},
-{0x8aa9,    0x0096}, {0x8aaa,    0x0022}, {0x8aab,    0x0084},
-{0x8aac,    0x0080}, {0x8aad,    0x0044}, {0x8aae,    0x0044},
-{0x8aaf,    0x0044}, {0x8ab0,    0x001b}, {0x8ab1,    0x00d6},
-{0x8ab2,    0x0022}, {0x8ab3,    0x00c4}, {0x8ab4,    0x006f},
-{0x8ab5,    0x001b}, {0x8ab6,    0x0097}, {0x8ab7,    0x0022},
-{0x8ab8,    0x0039}, {0x8ab9,    0x0027}, {0x8aba,    0x000c},
-{0x8abb,    0x007c}, {0x8abc,    0x0082}, {0x8abd,    0x0006},
-{0x8abe,    0x00bd}, {0x8abf,    0x00d9}, {0x8ac0,    0x00ed},
-{0x8ac1,    0x00b6}, {0x8ac2,    0x0082}, {0x8ac3,    0x0007},
-{0x8ac4,    0x007e}, {0x8ac5,    0x008a}, {0x8ac6,    0x00b9},
-{0x8ac7,    0x007f}, {0x8ac8,    0x0082}, {0x8ac9,    0x0006},
-{0x8aca,    0x0039}, { 0x0, 0x0 }
-};
-#endif
-
-
 /* phy types */
 #define   CAS_PHY_UNKNOWN       0x00
 #define   CAS_PHY_SERDES        0x01
@@ -4389,6 +2872,11 @@ struct cas {
        dma_addr_t block_dvma, tx_tiny_dvma[N_TX_RINGS];
        struct pci_dev *pdev;
        struct net_device *dev;
+
+       /* Firmware Info */
+       u16                     fw_load_addr;
+       u32                     fw_size;
+       u8                      *fw_data;
 };
 
 #define TX_DESC_NEXT(r, x)  (((x) + 1) & (TX_DESC_RINGN_SIZE(r) - 1))
index ea6144a9565e571665db792b7686a31ff991c823..b0b66766ed27bf8de0d1c46f67283b9b030025ed 100644 (file)
@@ -1397,9 +1397,7 @@ net_open(struct net_device *dev)
 release_dma:
 #if ALLOW_DMA
                free_dma(dev->dma);
-#endif
 release_irq:
-#if ALLOW_DMA
                release_dma_buff(lp);
 #endif
                 writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON));
index 271140433b09a68eaa7219873185e21cb3bd27b0..4f5cc6987ec18a4ad479ef70ac3626c9e867e1cb 100644 (file)
@@ -124,8 +124,7 @@ struct sge_rspq {           /* state for an SGE response queue */
        dma_addr_t phys_addr;   /* physical address of the ring */
        unsigned int cntxt_id;  /* SGE context id for the response q */
        spinlock_t lock;        /* guards response processing */
-       struct sk_buff *rx_head;        /* offload packet receive queue head */
-       struct sk_buff *rx_tail;        /* offload packet receive queue tail */
+       struct sk_buff_head rx_queue; /* offload packet receive queue */
        struct sk_buff *pg_skb; /* used to build frag list in napi handler */
 
        unsigned long offload_pkts;
index c5b3de1bb45625a688ee7d020e723545284f0947..0f6fd63b28475cdf5bc0be26ebb5cf07cd88035d 100644 (file)
@@ -1018,7 +1018,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
 
        skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
        if (!skb) {
-               printk(KERN_ERR "%s: cannot allocate skb!\n", __FUNCTION__);
+               printk(KERN_ERR "%s: cannot allocate skb!\n", __func__);
                return;
        }
        skb->priority = CPL_PRIORITY_CONTROL;
@@ -1049,14 +1049,14 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
                return;
        if (!is_offloading(newdev)) {
                printk(KERN_WARNING "%s: Redirect to non-offload "
-                      "device ignored.\n", __FUNCTION__);
+                      "device ignored.\n", __func__);
                return;
        }
        tdev = dev2t3cdev(olddev);
        BUG_ON(!tdev);
        if (tdev != dev2t3cdev(newdev)) {
                printk(KERN_WARNING "%s: Redirect to different "
-                      "offload device ignored.\n", __FUNCTION__);
+                      "offload device ignored.\n", __func__);
                return;
        }
 
@@ -1064,7 +1064,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
        e = t3_l2t_get(tdev, new->neighbour, newdev);
        if (!e) {
                printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n",
-                      __FUNCTION__);
+                      __func__);
                return;
        }
 
index 825e510bd9ed7019a70b4115c385f521b80fcbf6..b2c5314582aa0cb954872d29127388f8edc5645c 100644 (file)
@@ -86,6 +86,7 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb,
                                  struct l2t_entry *e)
 {
        struct cpl_l2t_write_req *req;
+       struct sk_buff *tmp;
 
        if (!skb) {
                skb = alloc_skb(sizeof(*req), GFP_ATOMIC);
@@ -103,13 +104,11 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb,
        memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac));
        skb->priority = CPL_PRIORITY_CONTROL;
        cxgb3_ofld_send(dev, skb);
-       while (e->arpq_head) {
-               skb = e->arpq_head;
-               e->arpq_head = skb->next;
-               skb->next = NULL;
+
+       skb_queue_walk_safe(&e->arpq, skb, tmp) {
+               __skb_unlink(skb, &e->arpq);
                cxgb3_ofld_send(dev, skb);
        }
-       e->arpq_tail = NULL;
        e->state = L2T_STATE_VALID;
 
        return 0;
@@ -121,12 +120,7 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb,
  */
 static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb)
 {
-       skb->next = NULL;
-       if (e->arpq_head)
-               e->arpq_tail->next = skb;
-       else
-               e->arpq_head = skb;
-       e->arpq_tail = skb;
+       __skb_queue_tail(&e->arpq, skb);
 }
 
 int t3_l2t_send_slow(struct t3cdev *dev, struct sk_buff *skb,
@@ -167,7 +161,7 @@ again:
                                break;
 
                        spin_lock_bh(&e->lock);
-                       if (e->arpq_head)
+                       if (!skb_queue_empty(&e->arpq))
                                setup_l2e_send_pending(dev, skb, e);
                        else    /* we lost the race */
                                __kfree_skb(skb);
@@ -357,14 +351,14 @@ EXPORT_SYMBOL(t3_l2t_get);
  * XXX: maybe we should abandon the latter behavior and just require a failure
  * handler.
  */
-static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff *arpq)
+static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff_head *arpq)
 {
-       while (arpq) {
-               struct sk_buff *skb = arpq;
+       struct sk_buff *skb, *tmp;
+
+       skb_queue_walk_safe(arpq, skb, tmp) {
                struct l2t_skb_cb *cb = L2T_SKB_CB(skb);
 
-               arpq = skb->next;
-               skb->next = NULL;
+               __skb_unlink(skb, arpq);
                if (cb->arp_failure_handler)
                        cb->arp_failure_handler(dev, skb);
                else
@@ -378,8 +372,8 @@ static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff *arpq)
  */
 void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh)
 {
+       struct sk_buff_head arpq;
        struct l2t_entry *e;
-       struct sk_buff *arpq = NULL;
        struct l2t_data *d = L2DATA(dev);
        u32 addr = *(u32 *) neigh->primary_key;
        int ifidx = neigh->dev->ifindex;
@@ -395,6 +389,8 @@ void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh)
        return;
 
 found:
+       __skb_queue_head_init(&arpq);
+
        read_unlock(&d->lock);
        if (atomic_read(&e->refcnt)) {
                if (neigh != e->neigh)
@@ -402,8 +398,7 @@ found:
 
                if (e->state == L2T_STATE_RESOLVING) {
                        if (neigh->nud_state & NUD_FAILED) {
-                               arpq = e->arpq_head;
-                               e->arpq_head = e->arpq_tail = NULL;
+                               skb_queue_splice_init(&e->arpq, &arpq);
                        } else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE))
                                setup_l2e_send_pending(dev, NULL, e);
                } else {
@@ -415,8 +410,8 @@ found:
        }
        spin_unlock_bh(&e->lock);
 
-       if (arpq)
-               handle_failed_resolution(dev, arpq);
+       if (!skb_queue_empty(&arpq))
+               handle_failed_resolution(dev, &arpq);
 }
 
 struct l2t_data *t3_init_l2t(unsigned int l2t_capacity)
index d79001336cfdcaf6e4c0afdb9ac32aa7223519ec..42ce65f76a87517904bd89b4378cace767c53580 100644 (file)
@@ -64,8 +64,7 @@ struct l2t_entry {
        struct neighbour *neigh;        /* associated neighbour */
        struct l2t_entry *first;        /* start of hash chain */
        struct l2t_entry *next; /* next l2t_entry on chain */
-       struct sk_buff *arpq_head;      /* queue of packets awaiting resolution */
-       struct sk_buff *arpq_tail;
+       struct sk_buff_head arpq;       /* queue of packets awaiting resolution */
        spinlock_t lock;
        atomic_t refcnt;        /* entry reference count */
        u8 dmac[6];             /* neighbour's MAC address */
index 1b0861d73ab7d00ef103ab2d58de7975b134ab20..89efd04be4e0d340bfae3a68f144281ae68cafaf 100644 (file)
@@ -1704,16 +1704,15 @@ int t3_offload_tx(struct t3cdev *tdev, struct sk_buff *skb)
  */
 static inline void offload_enqueue(struct sge_rspq *q, struct sk_buff *skb)
 {
-       skb->next = skb->prev = NULL;
-       if (q->rx_tail)
-               q->rx_tail->next = skb;
-       else {
+       int was_empty = skb_queue_empty(&q->rx_queue);
+
+       __skb_queue_tail(&q->rx_queue, skb);
+
+       if (was_empty) {
                struct sge_qset *qs = rspq_to_qset(q);
 
                napi_schedule(&qs->napi);
-               q->rx_head = skb;
        }
-       q->rx_tail = skb;
 }
 
 /**
@@ -1754,26 +1753,29 @@ static int ofld_poll(struct napi_struct *napi, int budget)
        int work_done = 0;
 
        while (work_done < budget) {
-               struct sk_buff *head, *tail, *skbs[RX_BUNDLE_SIZE];
+               struct sk_buff *skb, *tmp, *skbs[RX_BUNDLE_SIZE];
+               struct sk_buff_head queue;
                int ngathered;
 
                spin_lock_irq(&q->lock);
-               head = q->rx_head;
-               if (!head) {
+               __skb_queue_head_init(&queue);
+               skb_queue_splice_init(&q->rx_queue, &queue);
+               if (skb_queue_empty(&queue)) {
                        napi_complete(napi);
                        spin_unlock_irq(&q->lock);
                        return work_done;
                }
-
-               tail = q->rx_tail;
-               q->rx_head = q->rx_tail = NULL;
                spin_unlock_irq(&q->lock);
 
-               for (ngathered = 0; work_done < budget && head; work_done++) {
-                       prefetch(head->data);
-                       skbs[ngathered] = head;
-                       head = head->next;
-                       skbs[ngathered]->next = NULL;
+               ngathered = 0;
+               skb_queue_walk_safe(&queue, skb, tmp) {
+                       if (work_done >= budget)
+                               break;
+                       work_done++;
+
+                       __skb_unlink(skb, &queue);
+                       prefetch(skb->data);
+                       skbs[ngathered] = skb;
                        if (++ngathered == RX_BUNDLE_SIZE) {
                                q->offload_bundles++;
                                adapter->tdev.recv(&adapter->tdev, skbs,
@@ -1781,12 +1783,10 @@ static int ofld_poll(struct napi_struct *napi, int budget)
                                ngathered = 0;
                        }
                }
-               if (head) {     /* splice remaining packets back onto Rx queue */
+               if (!skb_queue_empty(&queue)) {
+                       /* splice remaining packets back onto Rx queue */
                        spin_lock_irq(&q->lock);
-                       tail->next = q->rx_head;
-                       if (!q->rx_head)
-                               q->rx_tail = tail;
-                       q->rx_head = head;
+                       skb_queue_splice(&queue, &q->rx_queue);
                        spin_unlock_irq(&q->lock);
                }
                deliver_partial_bundle(&adapter->tdev, q, skbs, ngathered);
@@ -1937,38 +1937,6 @@ static inline int lro_frame_ok(const struct cpl_rx_pkt *p)
                eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2);
 }
 
-#define TCP_FLAG_MASK (TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG |\
-                       TCP_FLAG_ACK | TCP_FLAG_PSH | TCP_FLAG_RST |\
-                                      TCP_FLAG_SYN | TCP_FLAG_FIN)
-#define TSTAMP_WORD ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |\
-                     (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)
-
-/**
- *     lro_segment_ok - check if a TCP segment is eligible for LRO
- *     @tcph: the TCP header of the packet
- *
- *     Returns true if a TCP packet is eligible for LRO.  This requires that
- *     the packet have only the ACK flag set and no TCP options besides
- *     time stamps.
- */
-static inline int lro_segment_ok(const struct tcphdr *tcph)
-{
-       int optlen;
-
-       if (unlikely((tcp_flag_word(tcph) & TCP_FLAG_MASK) != TCP_FLAG_ACK))
-               return 0;
-
-       optlen = (tcph->doff << 2) - sizeof(*tcph);
-       if (optlen) {
-               const u32 *opt = (const u32 *)(tcph + 1);
-
-               if (optlen != TCPOLEN_TSTAMP_ALIGNED ||
-                   *opt != htonl(TSTAMP_WORD) || !opt[2])
-                       return 0;
-       }
-       return 1;
-}
-
 static int t3_get_lro_header(void **eh,  void **iph, void **tcph,
                             u64 *hdr_flags, void *priv)
 {
@@ -1981,9 +1949,6 @@ static int t3_get_lro_header(void **eh,  void **iph, void **tcph,
        *iph = (struct iphdr *)((struct ethhdr *)*eh + 1);
        *tcph = (struct tcphdr *)((struct iphdr *)*iph + 1);
 
-        if (!lro_segment_ok(*tcph))
-               return -1;
-
        *hdr_flags = LRO_IPV4 | LRO_TCP;
        return 0;
 }
@@ -2934,6 +2899,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
        q->rspq.gen = 1;
        q->rspq.size = p->rspq_size;
        spin_lock_init(&q->rspq.lock);
+       skb_queue_head_init(&q->rspq.rx_queue);
 
        q->txq[TXQ_ETH].stop_thres = nports *
            flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3);
index 453115acaad231c0efb4b902db371760c5d5bf0c..3d69fae781cf5461949b4d9fccf1e9ce7244249d 100644 (file)
@@ -191,7 +191,7 @@ MODULE_PARM_DESC(use_io, "Force use of i/o access mode");
 #define DPRINTK(nlevel, klevel, fmt, args...) \
        (void)((NETIF_MSG_##nlevel & nic->msg_enable) && \
        printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \
-               __FUNCTION__ , ## args))
+               __func__ , ## args))
 
 #define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\
        PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \
@@ -2738,9 +2738,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
                nic->flags |= wol_magic;
 
        /* ack any pending wake events, disable PME */
-       err = pci_enable_wake(pdev, 0, 0);
-       if (err)
-               DPRINTK(PROBE, ERR, "Error clearing wake event\n");
+       pci_pme_active(pdev, false);
 
        strcpy(netdev->name, "eth%d");
        if((err = register_netdev(netdev))) {
index 19e317eaf5bc4582adb3279df31247368ad13da3..62f62970f978a4bc32bdc1c987a236056c9b6b84 100644 (file)
@@ -155,8 +155,6 @@ do {                                                                        \
 #endif
 
 #define E1000_MNG_VLAN_NONE (-1)
-/* Number of packet split data buffers (not including the header buffer) */
-#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1)
 
 /* wrapper around a pointer to a socket buffer,
  * so a DMA handle can be stored along with the buffer */
@@ -168,14 +166,6 @@ struct e1000_buffer {
        u16 next_to_watch;
 };
 
-struct e1000_ps_page {
-       struct page *ps_page[PS_PAGE_BUFFERS];
-};
-
-struct e1000_ps_page_dma {
-       u64 ps_page_dma[PS_PAGE_BUFFERS];
-};
-
 struct e1000_tx_ring {
        /* pointer to the descriptor ring memory */
        void *desc;
@@ -213,9 +203,6 @@ struct e1000_rx_ring {
        unsigned int next_to_clean;
        /* array of buffer information structs */
        struct e1000_buffer *buffer_info;
-       /* arrays of page information for packet split */
-       struct e1000_ps_page *ps_page;
-       struct e1000_ps_page_dma *ps_page_dma;
 
        /* cpu for rx queue */
        int cpu;
@@ -228,8 +215,6 @@ struct e1000_rx_ring {
        ((((R)->next_to_clean > (R)->next_to_use)                       \
          ? 0 : (R)->count) + (R)->next_to_clean - (R)->next_to_use - 1)
 
-#define E1000_RX_DESC_PS(R, i)                                         \
-       (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
 #define E1000_RX_DESC_EXT(R, i)                                                \
        (&(((union e1000_rx_desc_extended *)((R).desc))[i]))
 #define E1000_GET_DESC(R, i, type)     (&(((struct type *)((R).desc))[i]))
@@ -311,10 +296,8 @@ struct e1000_adapter {
        u32 rx_int_delay;
        u32 rx_abs_int_delay;
        bool rx_csum;
-       unsigned int rx_ps_pages;
        u32 gorcl;
        u64 gorcl_old;
-       u16 rx_ps_bsize0;
 
        /* OS defined structs */
        struct net_device *netdev;
index 9d6edf3e73f92998d8fb4f19ddbbfe64cd2ca4ac..d04eef53571e209bd0f49dafce91d89f759ccaf7 100644 (file)
@@ -144,6 +144,8 @@ static s32 e1000_host_if_read_cookie(struct e1000_hw *hw, u8 *buffer);
 static u8 e1000_calculate_mng_checksum(char *buffer, u32 length);
 static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex);
 static s32 e1000_configure_kmrn_for_1000(struct e1000_hw *hw);
+static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
+static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
 
 /* IGP cable length table */
 static const
@@ -168,6 +170,8 @@ u16 e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
       83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
       104, 109, 114, 118, 121, 124};
 
+static DEFINE_SPINLOCK(e1000_eeprom_lock);
+
 /******************************************************************************
  * Set the phy type member in the hw struct.
  *
@@ -4903,6 +4907,15 @@ static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw)
  * words - number of words to read
  *****************************************************************************/
 s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
+{
+    s32 ret;
+    spin_lock(&e1000_eeprom_lock);
+    ret = e1000_do_read_eeprom(hw, offset, words, data);
+    spin_unlock(&e1000_eeprom_lock);
+    return ret;
+}
+
+static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     u32 i = 0;
@@ -5235,6 +5248,16 @@ s32 e1000_update_eeprom_checksum(struct e1000_hw *hw)
  * EEPROM will most likely contain an invalid checksum.
  *****************************************************************************/
 s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
+{
+    s32 ret;
+    spin_lock(&e1000_eeprom_lock);
+    ret = e1000_do_write_eeprom(hw, offset, words, data);
+    spin_unlock(&e1000_eeprom_lock);
+    return ret;
+}
+
+
+static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 {
     struct e1000_eeprom_info *eeprom = &hw->eeprom;
     s32 status = 0;
index ad6da7b67e555023532134d64e6ac1efd326049f..2ab44db29fac308d1e800babe0bbf82143d1ca3a 100644 (file)
@@ -137,15 +137,9 @@ static int e1000_clean(struct napi_struct *napi, int budget);
 static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                               struct e1000_rx_ring *rx_ring,
                               int *work_done, int work_to_do);
-static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-                                 struct e1000_rx_ring *rx_ring,
-                                 int *work_done, int work_to_do);
 static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
                                    struct e1000_rx_ring *rx_ring,
                                   int cleaned_count);
-static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
-                                      struct e1000_rx_ring *rx_ring,
-                                     int cleaned_count);
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
                           int cmd);
@@ -1331,7 +1325,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
        pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word);
 
        adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE;
-       adapter->rx_ps_bsize0 = E1000_RXBUFFER_128;
        hw->max_frame_size = netdev->mtu +
                             ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
        hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
@@ -1815,26 +1808,6 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
        }
        memset(rxdr->buffer_info, 0, size);
 
-       rxdr->ps_page = kcalloc(rxdr->count, sizeof(struct e1000_ps_page),
-                               GFP_KERNEL);
-       if (!rxdr->ps_page) {
-               vfree(rxdr->buffer_info);
-               DPRINTK(PROBE, ERR,
-               "Unable to allocate memory for the receive descriptor ring\n");
-               return -ENOMEM;
-       }
-
-       rxdr->ps_page_dma = kcalloc(rxdr->count,
-                                   sizeof(struct e1000_ps_page_dma),
-                                   GFP_KERNEL);
-       if (!rxdr->ps_page_dma) {
-               vfree(rxdr->buffer_info);
-               kfree(rxdr->ps_page);
-               DPRINTK(PROBE, ERR,
-               "Unable to allocate memory for the receive descriptor ring\n");
-               return -ENOMEM;
-       }
-
        if (hw->mac_type <= e1000_82547_rev_2)
                desc_len = sizeof(struct e1000_rx_desc);
        else
@@ -1852,8 +1825,6 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
                "Unable to allocate memory for the receive descriptor ring\n");
 setup_rx_desc_die:
                vfree(rxdr->buffer_info);
-               kfree(rxdr->ps_page);
-               kfree(rxdr->ps_page_dma);
                return -ENOMEM;
        }
 
@@ -1932,11 +1903,7 @@ int e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
 static void e1000_setup_rctl(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
-       u32 rctl, rfctl;
-       u32 psrctl = 0;
-#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
-       u32 pages = 0;
-#endif
+       u32 rctl;
 
        rctl = er32(RCTL);
 
@@ -1988,55 +1955,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
                        break;
        }
 
-#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT
-       /* 82571 and greater support packet-split where the protocol
-        * header is placed in skb->data and the packet data is
-        * placed in pages hanging off of skb_shinfo(skb)->nr_frags.
-        * In the case of a non-split, skb->data is linearly filled,
-        * followed by the page buffers.  Therefore, skb->data is
-        * sized to hold the largest protocol header.
-        */
-       /* allocations using alloc_page take too long for regular MTU
-        * so only enable packet split for jumbo frames */
-       pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-       if ((hw->mac_type >= e1000_82571) && (pages <= 3) &&
-           PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE))
-               adapter->rx_ps_pages = pages;
-       else
-               adapter->rx_ps_pages = 0;
-#endif
-       if (adapter->rx_ps_pages) {
-               /* Configure extra packet-split registers */
-               rfctl = er32(RFCTL);
-               rfctl |= E1000_RFCTL_EXTEN;
-               /* disable packet split support for IPv6 extension headers,
-                * because some malformed IPv6 headers can hang the RX */
-               rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
-                         E1000_RFCTL_NEW_IPV6_EXT_DIS);
-
-               ew32(RFCTL, rfctl);
-
-               rctl |= E1000_RCTL_DTYP_PS;
-
-               psrctl |= adapter->rx_ps_bsize0 >>
-                       E1000_PSRCTL_BSIZE0_SHIFT;
-
-               switch (adapter->rx_ps_pages) {
-               case 3:
-                       psrctl |= PAGE_SIZE <<
-                               E1000_PSRCTL_BSIZE3_SHIFT;
-               case 2:
-                       psrctl |= PAGE_SIZE <<
-                               E1000_PSRCTL_BSIZE2_SHIFT;
-               case 1:
-                       psrctl |= PAGE_SIZE >>
-                               E1000_PSRCTL_BSIZE1_SHIFT;
-                       break;
-               }
-
-               ew32(PSRCTL, psrctl);
-       }
-
        ew32(RCTL, rctl);
 }
 
@@ -2053,18 +1971,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
        u32 rdlen, rctl, rxcsum, ctrl_ext;
 
-       if (adapter->rx_ps_pages) {
-               /* this is a 32 byte descriptor */
-               rdlen = adapter->rx_ring[0].count *
-                       sizeof(union e1000_rx_desc_packet_split);
-               adapter->clean_rx = e1000_clean_rx_irq_ps;
-               adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
-       } else {
-               rdlen = adapter->rx_ring[0].count *
-                       sizeof(struct e1000_rx_desc);
-               adapter->clean_rx = e1000_clean_rx_irq;
-               adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
-       }
+       rdlen = adapter->rx_ring[0].count *
+               sizeof(struct e1000_rx_desc);
+       adapter->clean_rx = e1000_clean_rx_irq;
+       adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
 
        /* disable receives while setting up the descriptors */
        rctl = er32(RCTL);
@@ -2109,28 +2019,14 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
        /* Enable 82543 Receive Checksum Offload for TCP and UDP */
        if (hw->mac_type >= e1000_82543) {
                rxcsum = er32(RXCSUM);
-               if (adapter->rx_csum) {
+               if (adapter->rx_csum)
                        rxcsum |= E1000_RXCSUM_TUOFL;
-
-                       /* Enable 82571 IPv4 payload checksum for UDP fragments
-                        * Must be used in conjunction with packet-split. */
-                       if ((hw->mac_type >= e1000_82571) &&
-                           (adapter->rx_ps_pages)) {
-                               rxcsum |= E1000_RXCSUM_IPPCSE;
-                       }
-               } else {
-                       rxcsum &= ~E1000_RXCSUM_TUOFL;
+               else
                        /* don't need to clear IPPCSE as it defaults to 0 */
-               }
+                       rxcsum &= ~E1000_RXCSUM_TUOFL;
                ew32(RXCSUM, rxcsum);
        }
 
-       /* enable early receives on 82573, only takes effect if using > 2048
-        * byte total frame size.  for example only for jumbo frames */
-#define E1000_ERT_2048 0x100
-       if (hw->mac_type == e1000_82573)
-               ew32(ERT, E1000_ERT_2048);
-
        /* Enable Receives */
        ew32(RCTL, rctl);
 }
@@ -2256,10 +2152,6 @@ static void e1000_free_rx_resources(struct e1000_adapter *adapter,
 
        vfree(rx_ring->buffer_info);
        rx_ring->buffer_info = NULL;
-       kfree(rx_ring->ps_page);
-       rx_ring->ps_page = NULL;
-       kfree(rx_ring->ps_page_dma);
-       rx_ring->ps_page_dma = NULL;
 
        pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma);
 
@@ -2292,11 +2184,9 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
 {
        struct e1000_hw *hw = &adapter->hw;
        struct e1000_buffer *buffer_info;
-       struct e1000_ps_page *ps_page;
-       struct e1000_ps_page_dma *ps_page_dma;
        struct pci_dev *pdev = adapter->pdev;
        unsigned long size;
-       unsigned int i, j;
+       unsigned int i;
 
        /* Free all the Rx ring sk_buffs */
        for (i = 0; i < rx_ring->count; i++) {
@@ -2310,25 +2200,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
                        dev_kfree_skb(buffer_info->skb);
                        buffer_info->skb = NULL;
                }
-               ps_page = &rx_ring->ps_page[i];
-               ps_page_dma = &rx_ring->ps_page_dma[i];
-               for (j = 0; j < adapter->rx_ps_pages; j++) {
-                       if (!ps_page->ps_page[j]) break;
-                       pci_unmap_page(pdev,
-                                      ps_page_dma->ps_page_dma[j],
-                                      PAGE_SIZE, PCI_DMA_FROMDEVICE);
-                       ps_page_dma->ps_page_dma[j] = 0;
-                       put_page(ps_page->ps_page[j]);
-                       ps_page->ps_page[j] = NULL;
-               }
        }
 
        size = sizeof(struct e1000_buffer) * rx_ring->count;
        memset(rx_ring->buffer_info, 0, size);
-       size = sizeof(struct e1000_ps_page) * rx_ring->count;
-       memset(rx_ring->ps_page, 0, size);
-       size = sizeof(struct e1000_ps_page_dma) * rx_ring->count;
-       memset(rx_ring->ps_page_dma, 0, size);
 
        /* Zero out the descriptor ring */
 
@@ -4234,181 +4109,6 @@ next_desc:
        return cleaned;
 }
 
-/**
- * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
- * @adapter: board private structure
- **/
-
-static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
-                                 struct e1000_rx_ring *rx_ring,
-                                 int *work_done, int work_to_do)
-{
-       union e1000_rx_desc_packet_split *rx_desc, *next_rxd;
-       struct net_device *netdev = adapter->netdev;
-       struct pci_dev *pdev = adapter->pdev;
-       struct e1000_buffer *buffer_info, *next_buffer;
-       struct e1000_ps_page *ps_page;
-       struct e1000_ps_page_dma *ps_page_dma;
-       struct sk_buff *skb;
-       unsigned int i, j;
-       u32 length, staterr;
-       int cleaned_count = 0;
-       bool cleaned = false;
-       unsigned int total_rx_bytes=0, total_rx_packets=0;
-
-       i = rx_ring->next_to_clean;
-       rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
-       staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
-       buffer_info = &rx_ring->buffer_info[i];
-
-       while (staterr & E1000_RXD_STAT_DD) {
-               ps_page = &rx_ring->ps_page[i];
-               ps_page_dma = &rx_ring->ps_page_dma[i];
-
-               if (unlikely(*work_done >= work_to_do))
-                       break;
-               (*work_done)++;
-
-               skb = buffer_info->skb;
-
-               /* in the packet split case this is header only */
-               prefetch(skb->data - NET_IP_ALIGN);
-
-               if (++i == rx_ring->count) i = 0;
-               next_rxd = E1000_RX_DESC_PS(*rx_ring, i);
-               prefetch(next_rxd);
-
-               next_buffer = &rx_ring->buffer_info[i];
-
-               cleaned = true;
-               cleaned_count++;
-               pci_unmap_single(pdev, buffer_info->dma,
-                                buffer_info->length,
-                                PCI_DMA_FROMDEVICE);
-
-               if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) {
-                       E1000_DBG("%s: Packet Split buffers didn't pick up"
-                                 " the full packet\n", netdev->name);
-                       dev_kfree_skb_irq(skb);
-                       goto next_desc;
-               }
-
-               if (unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) {
-                       dev_kfree_skb_irq(skb);
-                       goto next_desc;
-               }
-
-               length = le16_to_cpu(rx_desc->wb.middle.length0);
-
-               if (unlikely(!length)) {
-                       E1000_DBG("%s: Last part of the packet spanning"
-                                 " multiple descriptors\n", netdev->name);
-                       dev_kfree_skb_irq(skb);
-                       goto next_desc;
-               }
-
-               /* Good Receive */
-               skb_put(skb, length);
-
-               {
-               /* this looks ugly, but it seems compiler issues make it
-                  more efficient than reusing j */
-               int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
-
-               /* page alloc/put takes too long and effects small packet
-                * throughput, so unsplit small packets and save the alloc/put*/
-               if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) {
-                       u8 *vaddr;
-                       /* there is no documentation about how to call
-                        * kmap_atomic, so we can't hold the mapping
-                        * very long */
-                       pci_dma_sync_single_for_cpu(pdev,
-                               ps_page_dma->ps_page_dma[0],
-                               PAGE_SIZE,
-                               PCI_DMA_FROMDEVICE);
-                       vaddr = kmap_atomic(ps_page->ps_page[0],
-                                           KM_SKB_DATA_SOFTIRQ);
-                       memcpy(skb_tail_pointer(skb), vaddr, l1);
-                       kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
-                       pci_dma_sync_single_for_device(pdev,
-                               ps_page_dma->ps_page_dma[0],
-                               PAGE_SIZE, PCI_DMA_FROMDEVICE);
-                       /* remove the CRC */
-                       l1 -= 4;
-                       skb_put(skb, l1);
-                       goto copydone;
-               } /* if */
-               }
-
-               for (j = 0; j < adapter->rx_ps_pages; j++) {
-                       length = le16_to_cpu(rx_desc->wb.upper.length[j]);
-                       if (!length)
-                               break;
-                       pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j],
-                                       PAGE_SIZE, PCI_DMA_FROMDEVICE);
-                       ps_page_dma->ps_page_dma[j] = 0;
-                       skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0,
-                                          length);
-                       ps_page->ps_page[j] = NULL;
-                       skb->len += length;
-                       skb->data_len += length;
-                       skb->truesize += length;
-               }
-
-               /* strip the ethernet crc, problem is we're using pages now so
-                * this whole operation can get a little cpu intensive */
-               pskb_trim(skb, skb->len - 4);
-
-copydone:
-               total_rx_bytes += skb->len;
-               total_rx_packets++;
-
-               e1000_rx_checksum(adapter, staterr,
-                                 le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb);
-               skb->protocol = eth_type_trans(skb, netdev);
-
-               if (likely(rx_desc->wb.upper.header_status &
-                          cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)))
-                       adapter->rx_hdr_split++;
-
-               if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
-                       vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-                               le16_to_cpu(rx_desc->wb.middle.vlan));
-               } else {
-                       netif_receive_skb(skb);
-               }
-
-               netdev->last_rx = jiffies;
-
-next_desc:
-               rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF);
-               buffer_info->skb = NULL;
-
-               /* return some buffers to hardware, one at a time is too slow */
-               if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
-                       adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
-                       cleaned_count = 0;
-               }
-
-               /* use prefetched values */
-               rx_desc = next_rxd;
-               buffer_info = next_buffer;
-
-               staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
-       }
-       rx_ring->next_to_clean = i;
-
-       cleaned_count = E1000_DESC_UNUSED(rx_ring);
-       if (cleaned_count)
-               adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count);
-
-       adapter->total_rx_packets += total_rx_packets;
-       adapter->total_rx_bytes += total_rx_bytes;
-       adapter->net_stats.rx_bytes += total_rx_bytes;
-       adapter->net_stats.rx_packets += total_rx_packets;
-       return cleaned;
-}
-
 /**
  * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended
  * @adapter: address of board private structure
@@ -4520,104 +4220,6 @@ map_skb:
        }
 }
 
-/**
- * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split
- * @adapter: address of board private structure
- **/
-
-static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
-                                     struct e1000_rx_ring *rx_ring,
-                                     int cleaned_count)
-{
-       struct e1000_hw *hw = &adapter->hw;
-       struct net_device *netdev = adapter->netdev;
-       struct pci_dev *pdev = adapter->pdev;
-       union e1000_rx_desc_packet_split *rx_desc;
-       struct e1000_buffer *buffer_info;
-       struct e1000_ps_page *ps_page;
-       struct e1000_ps_page_dma *ps_page_dma;
-       struct sk_buff *skb;
-       unsigned int i, j;
-
-       i = rx_ring->next_to_use;
-       buffer_info = &rx_ring->buffer_info[i];
-       ps_page = &rx_ring->ps_page[i];
-       ps_page_dma = &rx_ring->ps_page_dma[i];
-
-       while (cleaned_count--) {
-               rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
-
-               for (j = 0; j < PS_PAGE_BUFFERS; j++) {
-                       if (j < adapter->rx_ps_pages) {
-                               if (likely(!ps_page->ps_page[j])) {
-                                       ps_page->ps_page[j] =
-                                               alloc_page(GFP_ATOMIC);
-                                       if (unlikely(!ps_page->ps_page[j])) {
-                                               adapter->alloc_rx_buff_failed++;
-                                               goto no_buffers;
-                                       }
-                                       ps_page_dma->ps_page_dma[j] =
-                                               pci_map_page(pdev,
-                                                           ps_page->ps_page[j],
-                                                           0, PAGE_SIZE,
-                                                           PCI_DMA_FROMDEVICE);
-                               }
-                               /* Refresh the desc even if buffer_addrs didn't
-                                * change because each write-back erases
-                                * this info.
-                                */
-                               rx_desc->read.buffer_addr[j+1] =
-                                    cpu_to_le64(ps_page_dma->ps_page_dma[j]);
-                       } else
-                               rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0);
-               }
-
-               skb = netdev_alloc_skb(netdev,
-                                      adapter->rx_ps_bsize0 + NET_IP_ALIGN);
-
-               if (unlikely(!skb)) {
-                       adapter->alloc_rx_buff_failed++;
-                       break;
-               }
-
-               /* Make buffer alignment 2 beyond a 16 byte boundary
-                * this will result in a 16 byte aligned IP header after
-                * the 14 byte MAC header is removed
-                */
-               skb_reserve(skb, NET_IP_ALIGN);
-
-               buffer_info->skb = skb;
-               buffer_info->length = adapter->rx_ps_bsize0;
-               buffer_info->dma = pci_map_single(pdev, skb->data,
-                                                 adapter->rx_ps_bsize0,
-                                                 PCI_DMA_FROMDEVICE);
-
-               rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma);
-
-               if (unlikely(++i == rx_ring->count)) i = 0;
-               buffer_info = &rx_ring->buffer_info[i];
-               ps_page = &rx_ring->ps_page[i];
-               ps_page_dma = &rx_ring->ps_page_dma[i];
-       }
-
-no_buffers:
-       if (likely(rx_ring->next_to_use != i)) {
-               rx_ring->next_to_use = i;
-               if (unlikely(i-- == 0)) i = (rx_ring->count - 1);
-
-               /* Force memory writes to complete before letting h/w
-                * know there are new descriptors to fetch.  (Only
-                * applicable for weak-ordered memory model archs,
-                * such as IA-64). */
-               wmb();
-               /* Hardware increments by 16 bytes, but packet split
-                * descriptors are 32 bytes...so we increment tail
-                * twice as much.
-                */
-               writel(i<<1, hw->hw_addr + rx_ring->rdt);
-       }
-}
-
 /**
  * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers.
  * @adapter:
index 019b9c0bcdcb9a950bf234002a5da3a73157ef9c..692251b60915999e79654d981401e3e2b69b2ffb 100644 (file)
@@ -398,6 +398,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 
        if (!timeout) {
                hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
+               extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
+               ew32(EXTCNF_CTRL, extcnf_ctrl);
                return -E1000_ERR_CONFIG;
        }
 
index 0925204cd2d8ccc9f64cde433855db2250a69d25..24d05cb700553fbefc306e0b99015c53dd4018f6 100644 (file)
@@ -4671,13 +4671,15 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
        ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
        if (!(le16_to_cpu(buf) & (1 << 0))) {
                /* Deep Smart Power Down (DSPD) */
-               e_warn("Warning: detected DSPD enabled in EEPROM\n");
+               dev_warn(&adapter->pdev->dev,
+                        "Warning: detected DSPD enabled in EEPROM\n");
        }
 
        ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
        if (le16_to_cpu(buf) & (3 << 2)) {
                /* ASPM enable */
-               e_warn("Warning: detected ASPM enabled in EEPROM\n");
+               dev_warn(&adapter->pdev->dev,
+                        "Warning: detected ASPM enabled in EEPROM\n");
        }
 }
 
index e01926b7b5b7609cffec07754b7781c77fe26b3f..5524271eedca51bcf824d35656d53d7178e1fc28 100644 (file)
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0092"
+#define DRV_VERSION    "EHEA_0093"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
 #define DLPAR_MEM_ADD      2
 #define DLPAR_MEM_REM      4
-#define EHEA_CAPABILITIES  (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD)
+#define EHEA_CAPABILITIES  (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD | DLPAR_MEM_REM)
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
        | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
index 156eb6320b4ee209369a80f5ec83f4740b7c63bf..2a33a613d9e65f9a96b7dc78de7095ce73af5501 100644 (file)
@@ -535,7 +535,7 @@ u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr)
                                       cb_logaddr,              /* R5 */
                                       0, 0, 0, 0, 0);          /* R6-R10 */
 #ifdef DEBUG
-       ehea_dmp(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea");
+       ehea_dump(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea");
 #endif
        return hret;
 }
index 140f05baafd822b97946e183e9f221cf602a8d41..db8a9257e680aaa81945c1b26be37afd6a18b025 100644 (file)
@@ -595,7 +595,8 @@ static int ehea_create_busmap_callback(unsigned long pfn,
        end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE);
        mr_len = *(unsigned long *)arg;
 
-       ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
+       if (!ehea_bmap)
+               ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
        if (!ehea_bmap)
                return -ENOMEM;
 
index aa0bf6e1c69493933b153b818dc7badc0866b84f..e1b441effbbec15b81de2fe4b2d36992ac993724 100644 (file)
@@ -110,7 +110,7 @@ spi_read_buf(struct enc28j60_net *priv, int len, u8 *data)
        }
        if (ret && netif_msg_drv(priv))
                printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
-                       __FUNCTION__, ret);
+                       __func__, ret);
 
        return ret;
 }
@@ -131,7 +131,7 @@ static int spi_write_buf(struct enc28j60_net *priv, int len,
                ret = spi_write(priv->spi, priv->spi_transfer_buf, len + 1);
                if (ret && netif_msg_drv(priv))
                        printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
-                               __FUNCTION__, ret);
+                               __func__, ret);
        }
        return ret;
 }
@@ -156,7 +156,7 @@ static u8 spi_read_op(struct enc28j60_net *priv, u8 op,
        ret = spi_write_then_read(priv->spi, tx_buf, 1, rx_buf, slen);
        if (ret)
                printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
-                       __FUNCTION__, ret);
+                       __func__, ret);
        else
                val = rx_buf[slen - 1];
 
@@ -176,14 +176,14 @@ static int spi_write_op(struct enc28j60_net *priv, u8 op,
        ret = spi_write(priv->spi, priv->spi_transfer_buf, 2);
        if (ret && netif_msg_drv(priv))
                printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n",
-                       __FUNCTION__, ret);
+                       __func__, ret);
        return ret;
 }
 
 static void enc28j60_soft_reset(struct enc28j60_net *priv)
 {
        if (netif_msg_hw(priv))
-               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
 
        spi_write_op(priv, ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);
        /* Errata workaround #1, CLKRDY check is unreliable,
@@ -357,7 +357,7 @@ static void enc28j60_mem_read(struct enc28j60_net *priv,
                reg = nolock_regw_read(priv, ERDPTL);
                if (reg != addr)
                        printk(KERN_DEBUG DRV_NAME ": %s() error writing ERDPT "
-                               "(0x%04x - 0x%04x)\n", __FUNCTION__, reg, addr);
+                               "(0x%04x - 0x%04x)\n", __func__, reg, addr);
        }
 #endif
        spi_read_buf(priv, len, data);
@@ -380,7 +380,7 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data)
                if (reg != TXSTART_INIT)
                        printk(KERN_DEBUG DRV_NAME
                                ": %s() ERWPT:0x%04x != 0x%04x\n",
-                               __FUNCTION__, reg, TXSTART_INIT);
+                               __func__, reg, TXSTART_INIT);
        }
 #endif
        /* Set the TXND pointer to correspond to the packet size given */
@@ -390,13 +390,13 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data)
        if (netif_msg_hw(priv))
                printk(KERN_DEBUG DRV_NAME
                        ": %s() after control byte ERWPT:0x%04x\n",
-                       __FUNCTION__, nolock_regw_read(priv, EWRPTL));
+                       __func__, nolock_regw_read(priv, EWRPTL));
        /* copy the packet into the transmit buffer */
        spi_write_buf(priv, len, data);
        if (netif_msg_hw(priv))
                printk(KERN_DEBUG DRV_NAME
                         ": %s() after write packet ERWPT:0x%04x, len=%d\n",
-                        __FUNCTION__, nolock_regw_read(priv, EWRPTL), len);
+                        __func__, nolock_regw_read(priv, EWRPTL), len);
        mutex_unlock(&priv->lock);
 }
 
@@ -495,7 +495,7 @@ static int enc28j60_set_hw_macaddr(struct net_device *ndev)
                if (netif_msg_drv(priv))
                        printk(KERN_DEBUG DRV_NAME
                                ": %s() Hardware must be disabled to set "
-                               "Mac address\n", __FUNCTION__);
+                               "Mac address\n", __func__);
                ret = -EBUSY;
        }
        mutex_unlock(&priv->lock);
@@ -575,7 +575,7 @@ static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
        if (start > 0x1FFF || end > 0x1FFF || start > end) {
                if (netif_msg_drv(priv))
                        printk(KERN_ERR DRV_NAME ": %s(%d, %d) RXFIFO "
-                               "bad parameters!\n", __FUNCTION__, start, end);
+                               "bad parameters!\n", __func__, start, end);
                return;
        }
        /* set receive buffer start + end */
@@ -591,7 +591,7 @@ static void nolock_txfifo_init(struct enc28j60_net *priv, u16 start, u16 end)
        if (start > 0x1FFF || end > 0x1FFF || start > end) {
                if (netif_msg_drv(priv))
                        printk(KERN_ERR DRV_NAME ": %s(%d, %d) TXFIFO "
-                               "bad parameters!\n", __FUNCTION__, start, end);
+                               "bad parameters!\n", __func__, start, end);
                return;
        }
        /* set transmit buffer start + end */
@@ -630,7 +630,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv)
        u8 reg;
 
        if (netif_msg_drv(priv))
-               printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __FUNCTION__,
+               printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __func__,
                        priv->full_duplex ? "FullDuplex" : "HalfDuplex");
 
        mutex_lock(&priv->lock);
@@ -661,7 +661,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv)
        if (reg == 0x00 || reg == 0xff) {
                if (netif_msg_drv(priv))
                        printk(KERN_DEBUG DRV_NAME ": %s() Invalid RevId %d\n",
-                               __FUNCTION__, reg);
+                               __func__, reg);
                return 0;
        }
 
@@ -724,7 +724,7 @@ static void enc28j60_hw_enable(struct enc28j60_net *priv)
        /* enable interrupts */
        if (netif_msg_hw(priv))
                printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n",
-                       __FUNCTION__);
+                       __func__);
 
        enc28j60_phy_write(priv, PHIE, PHIE_PGEIE | PHIE_PLNKIE);
 
@@ -888,7 +888,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
                if (netif_msg_rx_err(priv))
                        dev_err(&ndev->dev,
                                "%s() Invalid packet address!! 0x%04x\n",
-                               __FUNCTION__, priv->next_pk_ptr);
+                               __func__, priv->next_pk_ptr);
                /* packet address corrupted: reset RX logic */
                mutex_lock(&priv->lock);
                nolock_reg_bfclr(priv, ECON1, ECON1_RXEN);
@@ -917,7 +917,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
        rxstat |= rsv[4];
 
        if (netif_msg_rx_status(priv))
-               enc28j60_dump_rsv(priv, __FUNCTION__, next_packet, len, rxstat);
+               enc28j60_dump_rsv(priv, __func__, next_packet, len, rxstat);
 
        if (!RSV_GETBIT(rxstat, RSV_RXOK)) {
                if (netif_msg_rx_err(priv))
@@ -941,7 +941,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
                        enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv),
                                        len, skb_put(skb, len));
                        if (netif_msg_pktdata(priv))
-                               dump_packet(__FUNCTION__, skb->len, skb->data);
+                               dump_packet(__func__, skb->len, skb->data);
                        skb->protocol = eth_type_trans(skb, ndev);
                        /* update statistics */
                        ndev->stats.rx_packets++;
@@ -958,7 +958,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
        erxrdpt = erxrdpt_workaround(next_packet, RXSTART_INIT, RXEND_INIT);
        if (netif_msg_hw(priv))
                printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT:0x%04x\n",
-                       __FUNCTION__, erxrdpt);
+                       __func__, erxrdpt);
 
        mutex_lock(&priv->lock);
        nolock_regw_write(priv, ERXRDPTL, erxrdpt);
@@ -968,7 +968,7 @@ static void enc28j60_hw_rx(struct net_device *ndev)
                reg = nolock_regw_read(priv, ERXRDPTL);
                if (reg != erxrdpt)
                        printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT verify "
-                               "error (0x%04x - 0x%04x)\n", __FUNCTION__,
+                               "error (0x%04x - 0x%04x)\n", __func__,
                                reg, erxrdpt);
        }
 #endif
@@ -1006,7 +1006,7 @@ static int enc28j60_get_free_rxfifo(struct enc28j60_net *priv)
        mutex_unlock(&priv->lock);
        if (netif_msg_rx_status(priv))
                printk(KERN_DEBUG DRV_NAME ": %s() free_space = %d\n",
-                       __FUNCTION__, free_space);
+                       __func__, free_space);
        return free_space;
 }
 
@@ -1022,7 +1022,7 @@ static void enc28j60_check_link_status(struct net_device *ndev)
        reg = enc28j60_phy_read(priv, PHSTAT2);
        if (netif_msg_hw(priv))
                printk(KERN_DEBUG DRV_NAME ": %s() PHSTAT1: %04x, "
-                       "PHSTAT2: %04x\n", __FUNCTION__,
+                       "PHSTAT2: %04x\n", __func__,
                        enc28j60_phy_read(priv, PHSTAT1), reg);
        duplex = reg & PHSTAT2_DPXSTAT;
 
@@ -1095,7 +1095,7 @@ static void enc28j60_irq_work_handler(struct work_struct *work)
        int intflags, loop;
 
        if (netif_msg_intr(priv))
-               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
        /* disable further interrupts */
        locked_reg_bfclr(priv, EIE, EIE_INTIE);
 
@@ -1198,7 +1198,7 @@ static void enc28j60_irq_work_handler(struct work_struct *work)
        /* re-enable interrupts */
        locked_reg_bfset(priv, EIE, EIE_INTIE);
        if (netif_msg_intr(priv))
-               printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __FUNCTION__);
+               printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __func__);
 }
 
 /*
@@ -1213,7 +1213,7 @@ static void enc28j60_hw_tx(struct enc28j60_net *priv)
                        ": Tx Packet Len:%d\n", priv->tx_skb->len);
 
        if (netif_msg_pktdata(priv))
-               dump_packet(__FUNCTION__,
+               dump_packet(__func__,
                            priv->tx_skb->len, priv->tx_skb->data);
        enc28j60_packet_write(priv, priv->tx_skb->len, priv->tx_skb->data);
 
@@ -1254,7 +1254,7 @@ static int enc28j60_send_packet(struct sk_buff *skb, struct net_device *dev)
        struct enc28j60_net *priv = netdev_priv(dev);
 
        if (netif_msg_tx_queued(priv))
-               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
 
        /* If some error occurs while trying to transmit this
         * packet, you should return '1' from this function.
@@ -1325,7 +1325,7 @@ static int enc28j60_net_open(struct net_device *dev)
        struct enc28j60_net *priv = netdev_priv(dev);
 
        if (netif_msg_drv(priv))
-               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
 
        if (!is_valid_ether_addr(dev->dev_addr)) {
                if (netif_msg_ifup(priv)) {
@@ -1363,7 +1363,7 @@ static int enc28j60_net_close(struct net_device *dev)
        struct enc28j60_net *priv = netdev_priv(dev);
 
        if (netif_msg_drv(priv))
-               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__);
+               printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__);
 
        enc28j60_hw_disable(priv);
        enc28j60_lowpower(priv, true);
index fb83c926da580df141b0cee7ebcc5a213f55493b..7f677e89a78875311c5b7a51b09ec14349079770 100644 (file)
@@ -33,7 +33,7 @@
 
 #define DRV_NAME               "enic"
 #define DRV_DESCRIPTION                "Cisco 10G Ethernet Driver"
-#define DRV_VERSION            "0.0.1.18163.472"
+#define DRV_VERSION            "0.0.1-18163.472-k1"
 #define DRV_COPYRIGHT          "Copyright 2008 Cisco Systems, Inc"
 #define PFX                    DRV_NAME ": "
 
@@ -75,7 +75,6 @@ struct enic {
        struct vnic_enet_config config;
        struct vnic_dev_bar bar0;
        struct vnic_dev *vdev;
-       struct net_device_stats net_stats;
        struct timer_list notify_timer;
        struct work_struct reset;
        struct msix_entry msix_entry[ENIC_MSIX_MAX];
index 4cf5ec76c9935515b7d96ba814fcd966fd288117..f3a47a87dbbe3206304d2827187e2561780d165a 100644 (file)
@@ -43,7 +43,6 @@
 #include "enic.h"
 
 #define ENIC_NOTIFY_TIMER_PERIOD       (2 * HZ)
-#define ENIC_JUMBO_FIRST_BUF_SIZE      256
 
 /* Supported devices */
 static struct pci_device_id enic_id_table[] = {
@@ -167,9 +166,14 @@ static void enic_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
        }
 }
 
-static int enic_get_stats_count(struct net_device *netdev)
+static int enic_get_sset_count(struct net_device *netdev, int sset)
 {
-       return enic_n_tx_stats + enic_n_rx_stats;
+       switch (sset) {
+       case ETH_SS_STATS:
+               return enic_n_tx_stats + enic_n_rx_stats;
+       default:
+               return -EOPNOTSUPP;
+       }
 }
 
 static void enic_get_ethtool_stats(struct net_device *netdev,
@@ -199,8 +203,10 @@ static int enic_set_rx_csum(struct net_device *netdev, u32 data)
 {
        struct enic *enic = netdev_priv(netdev);
 
-       enic->csum_rx_enabled =
-               (data && ENIC_SETTING(enic, RXCSUM)) ? 1 : 0;
+       if (data && !ENIC_SETTING(enic, RXCSUM))
+               return -EINVAL;
+
+       enic->csum_rx_enabled = !!data;
 
        return 0;
 }
@@ -209,7 +215,10 @@ static int enic_set_tx_csum(struct net_device *netdev, u32 data)
 {
        struct enic *enic = netdev_priv(netdev);
 
-       if (data && ENIC_SETTING(enic, TXCSUM))
+       if (data && !ENIC_SETTING(enic, TXCSUM))
+               return -EINVAL;
+
+       if (data)
                netdev->features |= NETIF_F_HW_CSUM;
        else
                netdev->features &= ~NETIF_F_HW_CSUM;
@@ -221,7 +230,10 @@ static int enic_set_tso(struct net_device *netdev, u32 data)
 {
        struct enic *enic = netdev_priv(netdev);
 
-       if (data && ENIC_SETTING(enic, TSO))
+       if (data && !ENIC_SETTING(enic, TSO))
+               return -EINVAL;
+
+       if (data)
                netdev->features |=
                        NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN;
        else
@@ -250,7 +262,7 @@ static struct ethtool_ops enic_ethtool_ops = {
        .set_msglevel = enic_set_msglevel,
        .get_link = ethtool_op_get_link,
        .get_strings = enic_get_strings,
-       .get_stats_count = enic_get_stats_count,
+       .get_sset_count = enic_get_sset_count,
        .get_ethtool_stats = enic_get_ethtool_stats,
        .get_rx_csum = enic_get_rx_csum,
        .set_rx_csum = enic_set_rx_csum,
@@ -652,25 +664,26 @@ static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
 static struct net_device_stats *enic_get_stats(struct net_device *netdev)
 {
        struct enic *enic = netdev_priv(netdev);
+       struct net_device_stats *net_stats = &netdev->stats;
        struct vnic_stats *stats;
 
        spin_lock(&enic->devcmd_lock);
        vnic_dev_stats_dump(enic->vdev, &stats);
        spin_unlock(&enic->devcmd_lock);
 
-       enic->net_stats.tx_packets = stats->tx.tx_frames_ok;
-       enic->net_stats.tx_bytes = stats->tx.tx_bytes_ok;
-       enic->net_stats.tx_errors = stats->tx.tx_errors;
-       enic->net_stats.tx_dropped = stats->tx.tx_drops;
+       net_stats->tx_packets = stats->tx.tx_frames_ok;
+       net_stats->tx_bytes = stats->tx.tx_bytes_ok;
+       net_stats->tx_errors = stats->tx.tx_errors;
+       net_stats->tx_dropped = stats->tx.tx_drops;
 
-       enic->net_stats.rx_packets = stats->rx.rx_frames_ok;
-       enic->net_stats.rx_bytes = stats->rx.rx_bytes_ok;
-       enic->net_stats.rx_errors = stats->rx.rx_errors;
-       enic->net_stats.multicast = stats->rx.rx_multicast_frames_ok;
-       enic->net_stats.rx_crc_errors = stats->rx.rx_crc_errors;
-       enic->net_stats.rx_dropped = stats->rx.rx_no_bufs;
+       net_stats->rx_packets = stats->rx.rx_frames_ok;
+       net_stats->rx_bytes = stats->rx.rx_bytes_ok;
+       net_stats->rx_errors = stats->rx.rx_errors;
+       net_stats->multicast = stats->rx.rx_multicast_frames_ok;
+       net_stats->rx_crc_errors = stats->rx.rx_crc_errors;
+       net_stats->rx_dropped = stats->rx.rx_no_bufs;
 
-       return &enic->net_stats;
+       return net_stats;
 }
 
 static void enic_reset_mcaddrs(struct enic *enic)
@@ -941,7 +954,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
 
                if (enic->vlan_group && vlan_stripped) {
 
-                       if (ENIC_SETTING(enic, LRO))
+                       if (ENIC_SETTING(enic, LRO) && ipv4)
                                lro_vlan_hwaccel_receive_skb(&enic->lro_mgr,
                                        skb, enic->vlan_group,
                                        vlan, cq_desc);
@@ -951,7 +964,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
 
                } else {
 
-                       if (ENIC_SETTING(enic, LRO))
+                       if (ENIC_SETTING(enic, LRO) && ipv4)
                                lro_receive_skb(&enic->lro_mgr, skb, cq_desc);
                        else
                                netif_receive_skb(skb);
@@ -1109,7 +1122,8 @@ static void enic_notify_timer(unsigned long data)
 
        enic_notify_check(enic);
 
-       mod_timer(&enic->notify_timer, round_jiffies(ENIC_NOTIFY_TIMER_PERIOD));
+       mod_timer(&enic->notify_timer,
+               round_jiffies(jiffies + ENIC_NOTIFY_TIMER_PERIOD));
 }
 
 static void enic_free_intr(struct enic *enic)
@@ -1119,9 +1133,11 @@ static void enic_free_intr(struct enic *enic)
 
        switch (vnic_dev_get_intr_mode(enic->vdev)) {
        case VNIC_DEV_INTR_MODE_INTX:
-       case VNIC_DEV_INTR_MODE_MSI:
                free_irq(enic->pdev->irq, netdev);
                break;
+       case VNIC_DEV_INTR_MODE_MSI:
+               free_irq(enic->pdev->irq, enic);
+               break;
        case VNIC_DEV_INTR_MODE_MSIX:
                for (i = 0; i < ARRAY_SIZE(enic->msix); i++)
                        if (enic->msix[i].requested)
@@ -1156,12 +1172,12 @@ static int enic_request_intr(struct enic *enic)
        case VNIC_DEV_INTR_MODE_MSIX:
 
                sprintf(enic->msix[ENIC_MSIX_RQ].devname,
-                       "%.11s-rx", netdev->name);
+                       "%.11s-rx-0", netdev->name);
                enic->msix[ENIC_MSIX_RQ].isr = enic_isr_msix_rq;
                enic->msix[ENIC_MSIX_RQ].devid = enic;
 
                sprintf(enic->msix[ENIC_MSIX_WQ].devname,
-                       "%.11s-tx", netdev->name);
+                       "%.11s-tx-0", netdev->name);
                enic->msix[ENIC_MSIX_WQ].isr = enic_isr_msix_wq;
                enic->msix[ENIC_MSIX_WQ].devid = enic;
 
@@ -1234,13 +1250,28 @@ static int enic_open(struct net_device *netdev)
        unsigned int i;
        int err;
 
+       err = enic_request_intr(enic);
+       if (err) {
+               printk(KERN_ERR PFX "%s: Unable to request irq.\n",
+                       netdev->name);
+               return err;
+       }
+
+       err = enic_notify_set(enic);
+       if (err) {
+               printk(KERN_ERR PFX
+                       "%s: Failed to alloc notify buffer, aborting.\n",
+                       netdev->name);
+               goto err_out_free_intr;
+       }
+
        for (i = 0; i < enic->rq_count; i++) {
                err = vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf);
                if (err) {
                        printk(KERN_ERR PFX
                                "%s: Unable to alloc receive buffers.\n",
                                netdev->name);
-                       return err;
+                       goto err_out_notify_unset;
                }
        }
 
@@ -1262,6 +1293,13 @@ static int enic_open(struct net_device *netdev)
        enic_notify_timer_start(enic);
 
        return 0;
+
+err_out_notify_unset:
+       vnic_dev_notify_unset(enic->vdev);
+err_out_free_intr:
+       enic_free_intr(enic);
+
+       return err;
 }
 
 /* rtnl lock is held, process context */
@@ -1291,6 +1329,9 @@ static int enic_stop(struct net_device *netdev)
                        return err;
        }
 
+       vnic_dev_notify_unset(enic->vdev);
+       enic_free_intr(enic);
+
        (void)vnic_cq_service(&enic->cq[ENIC_CQ_RQ],
                -1, enic_rq_service_drop, NULL);
        (void)vnic_cq_service(&enic->cq[ENIC_CQ_WQ],
@@ -1313,14 +1354,12 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu)
        struct enic *enic = netdev_priv(netdev);
        int running = netif_running(netdev);
 
+       if (new_mtu < ENIC_MIN_MTU || new_mtu > ENIC_MAX_MTU)
+               return -EINVAL;
+
        if (running)
                enic_stop(netdev);
 
-       if (new_mtu < ENIC_MIN_MTU)
-               new_mtu = ENIC_MIN_MTU;
-       if (new_mtu > ENIC_MAX_MTU)
-               new_mtu = ENIC_MAX_MTU;
-
        netdev->mtu = new_mtu;
 
        if (netdev->mtu > enic->port_mtu)
@@ -1578,18 +1617,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
                return -ENOMEM;
        }
 
-       /* Set the netdev name early so intr vectors are properly
-        * named and any error msgs can include netdev->name
-        */
-
-       rtnl_lock();
-       err = dev_alloc_name(netdev, netdev->name);
-       rtnl_unlock();
-       if (err < 0) {
-               printk(KERN_ERR PFX "Unable to allocate netdev name.\n");
-               goto err_out_free_netdev;
-       }
-
        pci_set_drvdata(pdev, netdev);
 
        SET_NETDEV_DEV(netdev, &pdev->dev);
@@ -1604,16 +1631,14 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        err = pci_enable_device(pdev);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: Cannot enable PCI device, aborting.\n",
-                       netdev->name);
+                       "Cannot enable PCI device, aborting.\n");
                goto err_out_free_netdev;
        }
 
        err = pci_request_regions(pdev, DRV_NAME);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: Cannot request PCI regions, aborting.\n",
-                       netdev->name);
+                       "Cannot request PCI regions, aborting.\n");
                goto err_out_disable_device;
        }
 
@@ -1629,25 +1654,22 @@ static int __devinit enic_probe(struct pci_dev *pdev,
                err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
                if (err) {
                        printk(KERN_ERR PFX
-                               "%s: No usable DMA configuration, aborting.\n",
-                               netdev->name);
+                               "No usable DMA configuration, aborting.\n");
                        goto err_out_release_regions;
                }
                err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
                if (err) {
                        printk(KERN_ERR PFX
-                               "%s: Unable to obtain 32-bit DMA "
-                               "for consistent allocations, aborting.\n",
-                               netdev->name);
+                               "Unable to obtain 32-bit DMA "
+                               "for consistent allocations, aborting.\n");
                        goto err_out_release_regions;
                }
        } else {
                err = pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK);
                if (err) {
                        printk(KERN_ERR PFX
-                               "%s: Unable to obtain 40-bit DMA "
-                               "for consistent allocations, aborting.\n",
-                               netdev->name);
+                               "Unable to obtain 40-bit DMA "
+                               "for consistent allocations, aborting.\n");
                        goto err_out_release_regions;
                }
                using_dac = 1;
@@ -1658,8 +1680,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 
        if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
                printk(KERN_ERR PFX
-                       "%s: BAR0 not memory-map'able, aborting.\n",
-                       netdev->name);
+                       "BAR0 not memory-map'able, aborting.\n");
                err = -ENODEV;
                goto err_out_release_regions;
        }
@@ -1670,8 +1691,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
 
        if (!enic->bar0.vaddr) {
                printk(KERN_ERR PFX
-                       "%s: Cannot memory-map BAR0 res hdr, aborting.\n",
-                       netdev->name);
+                       "Cannot memory-map BAR0 res hdr, aborting.\n");
                err = -ENODEV;
                goto err_out_release_regions;
        }
@@ -1682,8 +1702,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        enic->vdev = vnic_dev_register(NULL, enic, pdev, &enic->bar0);
        if (!enic->vdev) {
                printk(KERN_ERR PFX
-                       "%s: vNIC registration failed, aborting.\n",
-                       netdev->name);
+                       "vNIC registration failed, aborting.\n");
                err = -ENODEV;
                goto err_out_iounmap;
        }
@@ -1694,8 +1713,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        err = enic_dev_open(enic);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: vNIC dev open failed, aborting.\n",
-                       netdev->name);
+                       "vNIC dev open failed, aborting.\n");
                goto err_out_vnic_unregister;
        }
 
@@ -1712,8 +1730,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        err = vnic_dev_init(enic->vdev, 0);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: vNIC dev init failed, aborting.\n",
-                       netdev->name);
+                       "vNIC dev init failed, aborting.\n");
                goto err_out_dev_close;
        }
 
@@ -1723,8 +1740,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        err = enic_get_vnic_config(enic);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: Get vNIC configuration failed, aborting.\n",
-                       netdev->name);
+                       "Get vNIC configuration failed, aborting.\n");
                goto err_out_dev_close;
        }
 
@@ -1740,18 +1756,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        err = enic_set_intr_mode(enic);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: Failed to set intr mode, aborting.\n",
-                       netdev->name);
-               goto err_out_dev_close;
-       }
-
-       /* Request interrupt vector(s)
-       */
-
-       err = enic_request_intr(enic);
-       if (err) {
-               printk(KERN_ERR PFX "%s: Unable to request irq.\n",
-                       netdev->name);
+                       "Failed to set intr mode, aborting.\n");
                goto err_out_dev_close;
        }
 
@@ -1761,8 +1766,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        err = enic_alloc_vnic_resources(enic);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: Failed to alloc vNIC resources, aborting.\n",
-                       netdev->name);
+                       "Failed to alloc vNIC resources, aborting.\n");
                goto err_out_free_vnic_resources;
        }
 
@@ -1778,19 +1782,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
                ig_vlan_strip_en);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: Failed to config nic, aborting.\n",
-                       netdev->name);
-               goto err_out_free_vnic_resources;
-       }
-
-       /* Setup notification buffer area
-        */
-
-       err = enic_notify_set(enic);
-       if (err) {
-               printk(KERN_ERR PFX
-                       "%s: Failed to alloc notify buffer, aborting.\n",
-                       netdev->name);
+                       "Failed to config nic, aborting.\n");
                goto err_out_free_vnic_resources;
        }
 
@@ -1817,9 +1809,8 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        err = enic_set_mac_addr(netdev, enic->mac_addr);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: Invalid MAC address, aborting.\n",
-                       netdev->name);
-               goto err_out_notify_unset;
+                       "Invalid MAC address, aborting.\n");
+               goto err_out_free_vnic_resources;
        }
 
        netdev->open = enic_open;
@@ -1873,18 +1864,14 @@ static int __devinit enic_probe(struct pci_dev *pdev,
        err = register_netdev(netdev);
        if (err) {
                printk(KERN_ERR PFX
-                       "%s: Cannot register net device, aborting.\n",
-                       netdev->name);
-               goto err_out_notify_unset;
+                       "Cannot register net device, aborting.\n");
+               goto err_out_free_vnic_resources;
        }
 
        return 0;
 
-err_out_notify_unset:
-       vnic_dev_notify_unset(enic->vdev);
 err_out_free_vnic_resources:
        enic_free_vnic_resources(enic);
-       enic_free_intr(enic);
 err_out_dev_close:
        vnic_dev_close(enic->vdev);
 err_out_vnic_unregister:
@@ -1912,9 +1899,7 @@ static void __devexit enic_remove(struct pci_dev *pdev)
 
                flush_scheduled_work();
                unregister_netdev(netdev);
-               vnic_dev_notify_unset(enic->vdev);
                enic_free_vnic_resources(enic);
-               enic_free_intr(enic);
                vnic_dev_close(enic->vdev);
                enic_clear_intr_mode(enic);
                vnic_dev_unregister(enic->vdev);
index 0b6ecef9a849d6ea2238fcf807e6601d73ab8aca..cc7328b1552136f0fa7c8e8f5587b61e110f216b 100644 (file)
@@ -337,7 +337,7 @@ enum {
        NvRegMSIXIrqStatus = 0x3f0,
 
        NvRegPowerState2 = 0x600,
-#define NVREG_POWERSTATE2_POWERUP_MASK         0x0F11
+#define NVREG_POWERSTATE2_POWERUP_MASK         0x0F15
 #define NVREG_POWERSTATE2_POWERUP_REV_A3       0x0001
 #define NVREG_POWERSTATE2_PHY_RESET            0x0004
 };
@@ -5643,6 +5643,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
                dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
                writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
+               printk(KERN_DEBUG "nv_probe: set workaround bit for reversed mac addr\n");
        }
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
@@ -5890,14 +5891,12 @@ static void nv_restore_phy(struct net_device *dev)
        }
 }
 
-static void __devexit nv_remove(struct pci_dev *pci_dev)
+static void nv_restore_mac_addr(struct pci_dev *pci_dev)
 {
        struct net_device *dev = pci_get_drvdata(pci_dev);
        struct fe_priv *np = netdev_priv(dev);
        u8 __iomem *base = get_hwbase(dev);
 
-       unregister_netdev(dev);
-
        /* special op: write back the misordered MAC address - otherwise
         * the next nv_probe would see a wrong address.
         */
@@ -5905,6 +5904,15 @@ static void __devexit nv_remove(struct pci_dev *pci_dev)
        writel(np->orig_mac[1], base + NvRegMacAddrB);
        writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV,
               base + NvRegTransmitPoll);
+}
+
+static void __devexit nv_remove(struct pci_dev *pci_dev)
+{
+       struct net_device *dev = pci_get_drvdata(pci_dev);
+
+       unregister_netdev(dev);
+
+       nv_restore_mac_addr(pci_dev);
 
        /* restore any phy related changes */
        nv_restore_phy(dev);
@@ -5975,6 +5983,8 @@ static void nv_shutdown(struct pci_dev *pdev)
        if (netif_running(dev))
                nv_close(dev);
 
+       nv_restore_mac_addr(pdev);
+
        pci_disable_device(pdev);
        if (system_state == SYSTEM_POWER_OFF) {
                if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled))
index 9d461825bf4ce92e55a9de79921e8ffc94735617..cb51c1fb0338e722334dcab4f72e6f9abb79137d 100644 (file)
@@ -664,23 +664,6 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return NETDEV_TX_OK;
 }
 
-static int fs_request_irq(struct net_device *dev, int irq, const char *name,
-               irq_handler_t irqf)
-{
-       struct fs_enet_private *fep = netdev_priv(dev);
-
-       (*fep->ops->pre_request_irq)(dev, irq);
-       return request_irq(irq, irqf, IRQF_SHARED, name, dev);
-}
-
-static void fs_free_irq(struct net_device *dev, int irq)
-{
-       struct fs_enet_private *fep = netdev_priv(dev);
-
-       free_irq(irq, dev);
-       (*fep->ops->post_free_irq)(dev, irq);
-}
-
 static void fs_timeout(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
@@ -800,7 +783,8 @@ static int fs_enet_open(struct net_device *dev)
                napi_enable(&fep->napi);
 
        /* Install our interrupt handler. */
-       r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt);
+       r = request_irq(fep->interrupt, fs_enet_interrupt, IRQF_SHARED,
+                       "fs_enet-mac", dev);
        if (r != 0) {
                printk(KERN_ERR DRV_MODULE_NAME
                       ": %s Could not allocate FS_ENET IRQ!", dev->name);
@@ -842,7 +826,7 @@ static int fs_enet_close(struct net_device *dev)
        /* release any irqs */
        phy_disconnect(fep->phydev);
        fep->phydev = NULL;
-       fs_free_irq(dev, fep->interrupt);
+       free_irq(fep->interrupt, dev);
 
        return 0;
 }
index db46d2e723296b1f1dd1e0a1dce297f532370299..85a4bab7f6308a686df71a5f89bba96385419461 100644 (file)
@@ -34,8 +34,6 @@ struct fs_ops {
        void (*adjust_link)(struct net_device *dev);
        void (*restart)(struct net_device *dev);
        void (*stop)(struct net_device *dev);
-       void (*pre_request_irq)(struct net_device *dev, int irq);
-       void (*post_free_irq)(struct net_device *dev, int irq);
        void (*napi_clear_rx_event)(struct net_device *dev);
        void (*napi_enable_rx)(struct net_device *dev);
        void (*napi_disable_rx)(struct net_device *dev);
index 1c7ef812a8e3a42d8459b3b00133a9e7c7ba231e..22e5a847a58816043599bb9124b9e74d2b73da64 100644 (file)
@@ -421,16 +421,6 @@ static void stop(struct net_device *dev)
        fs_cleanup_bds(dev);
 }
 
-static void pre_request_irq(struct net_device *dev, int irq)
-{
-       /* nothing */
-}
-
-static void post_free_irq(struct net_device *dev, int irq)
-{
-       /* nothing */
-}
-
 static void napi_clear_rx_event(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
@@ -540,8 +530,6 @@ const struct fs_ops fs_fcc_ops = {
        .set_multicast_list     = set_multicast_list,
        .restart                = restart,
        .stop                   = stop,
-       .pre_request_irq        = pre_request_irq,
-       .post_free_irq          = post_free_irq,
        .napi_clear_rx_event    = napi_clear_rx_event,
        .napi_enable_rx         = napi_enable_rx,
        .napi_disable_rx        = napi_disable_rx,
index 0a7d1c5c652479e1f032764360dd4b8b320e5d02..14e575313c89c85c9573a85359368e0e320725a5 100644 (file)
@@ -313,11 +313,7 @@ static void restart(struct net_device *dev)
         * Clear any outstanding interrupt.
         */
        FW(fecp, ievent, 0xffc0);
-#ifndef CONFIG_PPC_MERGE
-       FW(fecp, ivec, (fep->interrupt / 2) << 29);
-#else
        FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
-#endif
 
        /*
         * adjust to speed (only for DUET & RMII)
@@ -413,30 +409,6 @@ static void stop(struct net_device *dev)
        }
 }
 
-static void pre_request_irq(struct net_device *dev, int irq)
-{
-#ifndef CONFIG_PPC_MERGE
-       immap_t *immap = fs_enet_immap;
-       u32 siel;
-
-       /* SIU interrupt */
-       if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) {
-
-               siel = in_be32(&immap->im_siu_conf.sc_siel);
-               if ((irq & 1) == 0)
-                       siel |= (0x80000000 >> irq);
-               else
-                       siel &= ~(0x80000000 >> (irq & ~1));
-               out_be32(&immap->im_siu_conf.sc_siel, siel);
-       }
-#endif
-}
-
-static void post_free_irq(struct net_device *dev, int irq)
-{
-       /* nothing */
-}
-
 static void napi_clear_rx_event(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
@@ -529,8 +501,6 @@ const struct fs_ops fs_fec_ops = {
        .set_multicast_list     = set_multicast_list,
        .restart                = restart,
        .stop                   = stop,
-       .pre_request_irq        = pre_request_irq,
-       .post_free_irq          = post_free_irq,
        .napi_clear_rx_event    = napi_clear_rx_event,
        .napi_enable_rx         = napi_enable_rx,
        .napi_disable_rx        = napi_disable_rx,
index 22f50dd8b2776adf126f76075d4bf7d8596e7346..008cdd9cc53601304cb5f68c8fc0ee35e8a392f0 100644 (file)
@@ -377,30 +377,6 @@ static void stop(struct net_device *dev)
        fs_cleanup_bds(dev);
 }
 
-static void pre_request_irq(struct net_device *dev, int irq)
-{
-#ifndef CONFIG_PPC_MERGE
-       immap_t *immap = fs_enet_immap;
-       u32 siel;
-
-       /* SIU interrupt */
-       if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) {
-
-               siel = in_be32(&immap->im_siu_conf.sc_siel);
-               if ((irq & 1) == 0)
-                       siel |= (0x80000000 >> irq);
-               else
-                       siel &= ~(0x80000000 >> (irq & ~1));
-               out_be32(&immap->im_siu_conf.sc_siel, siel);
-       }
-#endif
-}
-
-static void post_free_irq(struct net_device *dev, int irq)
-{
-       /* nothing */
-}
-
 static void napi_clear_rx_event(struct net_device *dev)
 {
        struct fs_enet_private *fep = netdev_priv(dev);
@@ -494,8 +470,6 @@ const struct fs_ops fs_scc_ops = {
        .set_multicast_list     = set_multicast_list,
        .restart                = restart,
        .stop                   = stop,
-       .pre_request_irq        = pre_request_irq,
-       .post_free_irq          = post_free_irq,
        .napi_clear_rx_event    = napi_clear_rx_event,
        .napi_enable_rx         = napi_enable_rx,
        .napi_disable_rx        = napi_disable_rx,
index ebcfb27a904eae72e7ca5ae5ee869acf5969496e..678f48c691194b6cb8852b6fdf3a7c6688db606f 100644 (file)
@@ -136,12 +136,12 @@ static int gfar_mdio_reset(struct mii_bus *bus)
 
        /* Wait until the bus is free */
        while ((gfar_read(&regs->miimind) & MIIMIND_BUSY) &&
-                       timeout--)
+                       --timeout)
                cpu_relax();
 
        mutex_unlock(&bus->mdio_lock);
 
-       if(timeout <= 0) {
+       if(timeout == 0) {
                printk(KERN_ERR "%s: The MII Bus is stuck!\n",
                                bus->name);
                return -EBUSY;
@@ -211,19 +211,21 @@ static int gfar_mdio_probe(struct device *dev)
        gfar_write(&enet_regs->tbipa, 0);
        for (i = PHY_MAX_ADDR; i > 0; i--) {
                u32 phy_id;
-               int r;
 
-               r = get_phy_id(new_bus, i, &phy_id);
-               if (r)
-                       return r;
+               err = get_phy_id(new_bus, i, &phy_id);
+               if (err)
+                       goto bus_register_fail;
 
                if (phy_id == 0xffffffff)
                        break;
        }
 
        /* The bus is full.  We don't support using 31 PHYs, sorry */
-       if (i == 0)
-               return -EBUSY;
+       if (i == 0) {
+               err = -EBUSY;
+
+               goto bus_register_fail;
+       }
 
        gfar_write(&enet_regs->tbipa, i);
 
index 8239939554bc4474735fb174c8f6f02da9957180..fbbd3e660c2731800bf6b7e136a62980bc51032f 100644 (file)
@@ -139,7 +139,7 @@ static int __init do_hpp_probe(struct net_device *dev)
 #ifndef MODULE
 struct net_device * __init hp_plus_probe(int unit)
 {
-       struct net_device *dev = alloc_ei_netdev();
+       struct net_device *dev = alloc_eip_netdev();
        int err;
 
        if (!dev)
@@ -284,7 +284,7 @@ hpp_open(struct net_device *dev)
        int option_reg;
        int retval;
 
-       if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) {
+       if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
            return retval;
        }
 
@@ -302,7 +302,7 @@ hpp_open(struct net_device *dev)
        /* Select the operational page. */
        outw(Perf_Page, ioaddr + HP_PAGING);
 
-       ei_open(dev);
+       eip_open(dev);
        return 0;
 }
 
@@ -313,7 +313,7 @@ hpp_close(struct net_device *dev)
        int option_reg = inw(ioaddr + HPP_OPTION);
 
        free_irq(dev->irq, dev);
-       ei_close(dev);
+       eip_close(dev);
        outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset,
                 ioaddr + HPP_OPTION);
 
index 70a3272ee998d646abf7b1c870237d827bc2967f..bcec7320895c889e96afaf7c067fa80438a4447a 100644 (file)
@@ -1,6 +1,6 @@
 config IBM_NEW_EMAC
        tristate "IBM EMAC Ethernet support"
-       depends on PPC_DCR && PPC_MERGE
+       depends on PPC_DCR
        select CRC32
        help
          This driver supports the IBM EMAC family of Ethernet controllers
index 37bfeea8788a71d601f6da1cf662b15fe466f55a..9164abb72d9bc908bac64e89a7ed5ddf6db1174e 100644 (file)
@@ -321,7 +321,7 @@ static struct mii_phy_def bcm5248_phy_def = {
 
 static int m88e1111_init(struct mii_phy *phy)
 {
-       pr_debug("%s: Marvell 88E1111 Ethernet\n", __FUNCTION__);
+       pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__);
        phy_write(phy, 0x14, 0x0ce3);
        phy_write(phy, 0x18, 0x4101);
        phy_write(phy, 0x09, 0x0e00);
index 18f4b3a96aedd1590eae4d3f13ba802011f9418e..9c926d205de971d69ee7873522ec4a657dfc8cfb 100644 (file)
@@ -165,7 +165,7 @@ static void vlsi_proc_pdev(struct seq_file *seq, struct pci_dev *pdev)
        unsigned iobase = pci_resource_start(pdev, 0);
        unsigned i;
 
-       seq_printf(seq, "\n%s (vid/did: %04x/%04x)\n",
+       seq_printf(seq, "\n%s (vid/did: [%04x:%04x])\n",
                   pci_name(pdev), (int)pdev->vendor, (int)pdev->device);
        seq_printf(seq, "pci-power-state: %u\n", (unsigned) pdev->current_state);
        seq_printf(seq, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n",
index 804698fc6a8fdb2f663c747f54960e8af3116a22..d85717e3022af0bcf6bae51c1828dc0c1eb2a5ff 100644 (file)
@@ -85,7 +85,7 @@ struct ixgb_adapter;
 #define DPRINTK(nlevel, klevel, fmt, args...) \
        (void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
        printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
-               __FUNCTION__ , ## args))
+               __func__ , ## args))
 
 
 /* TX/RX descriptor defines */
index 90b53830196c3302bb5498917e93b673eaaf0e97..2198b77c53ed07f8f089a3bdbed3ba1542c52aba 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 #include <linux/dca.h>
 #endif
 
-#define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args)
-
 #define PFX "ixgbe: "
 #define DPRINTK(nlevel, klevel, fmt, args...) \
        ((void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \
        printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \
-               __FUNCTION__ , ## args)))
+               __func__ , ## args)))
 
 /* TX/RX descriptor defines */
 #define IXGBE_DEFAULT_TXD                 1024
 #define IXGBE_MAX_RXD                     4096
 #define IXGBE_MIN_RXD                       64
 
-#define IXGBE_DEFAULT_RXQ                         1
-#define IXGBE_MAX_RXQ                             1
-#define IXGBE_MIN_RXQ                             1
-
-#define IXGBE_DEFAULT_ITR_RX_USECS         125  /*   8k irqs/sec */
-#define IXGBE_DEFAULT_ITR_TX_USECS         250  /*   4k irqs/sec */
-#define IXGBE_MIN_ITR_USECS                100  /* 500k irqs/sec */
-#define IXGBE_MAX_ITR_USECS              10000  /* 100  irqs/sec */
-
 /* flow control */
 #define IXGBE_DEFAULT_FCRTL            0x10000
 #define IXGBE_MIN_FCRTL                           0x40
@@ -88,9 +76,6 @@
 
 #define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN)
 
-/* How many Tx Descriptors do we need to call netif_wake_queue? */
-#define IXGBE_TX_QUEUE_WAKE 16
-
 /* How many Rx Buffers do we bundle into one write to the hardware ? */
 #define IXGBE_RX_BUFFER_WRITE  16      /* Must be power of 2 */
 
@@ -119,6 +104,7 @@ struct ixgbe_rx_buffer {
        dma_addr_t dma;
        struct page *page;
        dma_addr_t page_dma;
+       unsigned int page_offset;
 };
 
 struct ixgbe_queue_stats {
@@ -157,14 +143,11 @@ struct ixgbe_ring {
        struct net_lro_mgr lro_mgr;
        bool lro_used;
        struct ixgbe_queue_stats stats;
-       u8 v_idx; /* maps directly to the index for this ring in the hardware
-                  * vector array, can also be used for finding the bit in EICR
-                  * and friends that represents the vector for this ring */
+       u16 v_idx; /* maps directly to the index for this ring in the hardware
+                  * vector array, can also be used for finding the bit in EICR
+                  * and friends that represents the vector for this ring */
 
-       u32 eims_value;
-       u16 itr_register;
 
-       char name[IFNAMSIZ + 5];
        u16 work_limit;                /* max work per interrupt */
        u16 rx_buf_len;
 };
@@ -191,8 +174,8 @@ struct ixgbe_q_vector {
        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_eitr;
-       u8 rx_eitr;
+       u8 tx_itr;
+       u8 rx_itr;
        u32 eitr;
 };
 
@@ -240,7 +223,9 @@ struct ixgbe_adapter {
 
        /* TX */
        struct ixgbe_ring *tx_ring;     /* One per active queue */
+       int num_tx_queues;
        u64 restart_queue;
+       u64 hw_csum_tx_good;
        u64 lsc_int;
        u64 hw_tso_ctxt;
        u64 hw_tso6_ctxt;
@@ -249,12 +234,10 @@ struct ixgbe_adapter {
 
        /* RX */
        struct ixgbe_ring *rx_ring;     /* One per active queue */
-       u64 hw_csum_tx_good;
+       int num_rx_queues;
        u64 hw_csum_rx_error;
        u64 hw_csum_rx_good;
        u64 non_eop_descs;
-       int num_tx_queues;
-       int num_rx_queues;
        int num_msix_vectors;
        struct ixgbe_ring_feature ring_feature[3];
        struct msix_entry *msix_entries;
@@ -301,14 +284,21 @@ struct ixgbe_adapter {
        struct ixgbe_hw_stats stats;
 
        /* Interrupt Throttle Rate */
-       u32 rx_eitr;
-       u32 tx_eitr;
+       u32 eitr_param;
 
        unsigned long state;
        u64 tx_busy;
        u64 lro_aggregated;
        u64 lro_flushed;
        u64 lro_no_desc;
+       unsigned int tx_ring_count;
+       unsigned int rx_ring_count;
+
+       u32 link_speed;
+       bool link_up;
+       unsigned long link_check_timeout;
+
+       struct work_struct watchdog_task;
 };
 
 enum ixbge_state_t {
@@ -330,11 +320,11 @@ extern int ixgbe_up(struct ixgbe_adapter *adapter);
 extern void ixgbe_down(struct ixgbe_adapter *adapter);
 extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
 extern void ixgbe_reset(struct ixgbe_adapter *adapter);
-extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
 extern void ixgbe_set_ethtool_ops(struct net_device *netdev);
-extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
-                                   struct ixgbe_ring *rxdr);
-extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
-                                   struct ixgbe_ring *txdr);
+extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
+extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
 
 #endif /* _IXGBE_H_ */
index ba09063260d973bff94d87e336e9bce676111279..7cddcfba809e73bbd86a6ae108951de1f21376d3 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 #define IXGBE_82598_MC_TBL_SIZE  128
 #define IXGBE_82598_VFT_TBL_SIZE 128
 
-static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
-                                        bool *autoneg);
-static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
-                                               u32 *speed, bool *autoneg);
-static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
-                                     bool *link_up);
-static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
-                                           bool autoneg,
-                                           bool autoneg_wait_to_complete);
+static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
+                                             ixgbe_link_speed *speed,
+                                             bool *autoneg);
 static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw);
-static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
-                                              bool autoneg,
-                                              bool autoneg_wait_to_complete);
-static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw);
-
+static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
+                                               ixgbe_link_speed speed,
+                                               bool autoneg,
+                                               bool autoneg_wait_to_complete);
 
+/**
+ */
 static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
 {
-       hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
-       hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
-       hw->mac.mcft_size = IXGBE_82598_MC_TBL_SIZE;
-       hw->mac.vft_size = IXGBE_82598_VFT_TBL_SIZE;
-       hw->mac.num_rar_entries = IXGBE_82598_RAR_ENTRIES;
-
-       /* PHY ops are filled in by default properly for Fiber only */
-       if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) {
-               hw->mac.ops.setup_link = &ixgbe_setup_copper_link_82598;
-               hw->mac.ops.setup_link_speed = &ixgbe_setup_copper_link_speed_82598;
-               hw->mac.ops.get_link_settings =
-                               &ixgbe_get_copper_link_settings_82598;
-
-               /* Call PHY identify routine to get the phy type */
-               ixgbe_identify_phy(hw);
-
-               switch (hw->phy.type) {
-               case ixgbe_phy_tn:
-                       hw->phy.ops.setup_link = &ixgbe_setup_tnx_phy_link;
-                       hw->phy.ops.check_link = &ixgbe_check_tnx_phy_link;
-                       hw->phy.ops.setup_link_speed =
-                                       &ixgbe_setup_tnx_phy_link_speed;
-                       break;
-               default:
-                       break;
-               }
+       struct ixgbe_mac_info *mac = &hw->mac;
+       struct ixgbe_phy_info *phy = &hw->phy;
+
+       /* Call PHY identify routine to get the phy type */
+       ixgbe_identify_phy_generic(hw);
+
+       /* PHY Init */
+       switch (phy->type) {
+       default:
+               break;
        }
 
+       if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+               mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
+               mac->ops.setup_link_speed =
+                                    &ixgbe_setup_copper_link_speed_82598;
+               mac->ops.get_link_capabilities =
+                                    &ixgbe_get_copper_link_capabilities_82598;
+       }
+
+       mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
+       mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
+       mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
+       mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
+       mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+
        return 0;
 }
 
 /**
- *  ixgbe_get_link_settings_82598 - Determines default link settings
+ *  ixgbe_get_link_capabilities_82598 - Determines link capabilities
  *  @hw: pointer to hardware structure
  *  @speed: pointer to link speed
  *  @autoneg: boolean auto-negotiation value
  *
- *  Determines the default link settings by reading the AUTOC register.
+ *  Determines the link capabilities by reading the AUTOC register.
  **/
-static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
-                                        bool *autoneg)
+static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
+                                             ixgbe_link_speed *speed,
+                                             bool *autoneg)
 {
        s32 status = 0;
        s32 autoc_reg;
@@ -149,15 +139,16 @@ static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed,
 }
 
 /**
- *  ixgbe_get_copper_link_settings_82598 - Determines default link settings
+ *  ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities
  *  @hw: pointer to hardware structure
  *  @speed: pointer to link speed
  *  @autoneg: boolean auto-negotiation value
  *
- *  Determines the default link settings by reading the AUTOC register.
+ *  Determines the link capabilities by reading the AUTOC register.
  **/
-static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
-                                               u32 *speed, bool *autoneg)
+s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
+                                             ixgbe_link_speed *speed,
+                                             bool *autoneg)
 {
        s32 status = IXGBE_ERR_LINK_SETUP;
        u16 speed_ability;
@@ -165,9 +156,9 @@ static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw,
        *speed = 0;
        *autoneg = true;
 
-       status = ixgbe_read_phy_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
-                                   IXGBE_MDIO_PMA_PMD_DEV_TYPE,
-                                   &speed_ability);
+       status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
+                                     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+                                     &speed_ability);
 
        if (status == 0) {
                if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
@@ -195,11 +186,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
        case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
        case IXGBE_DEV_ID_82598EB_CX4:
        case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+       case IXGBE_DEV_ID_82598EB_XF_LR:
                media_type = ixgbe_media_type_fiber;
                break;
-       case IXGBE_DEV_ID_82598AT_DUAL_PORT:
-               media_type = ixgbe_media_type_copper;
-               break;
        default:
                media_type = ixgbe_media_type_unknown;
                break;
@@ -208,6 +197,122 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
        return media_type;
 }
 
+/**
+ *  ixgbe_setup_fc_82598 - Configure flow control settings
+ *  @hw: pointer to hardware structure
+ *  @packetbuf_num: packet buffer number (0-7)
+ *
+ *  Configures the flow control settings based on SW configuration.  This
+ *  function is used for 802.3x flow control configuration only.
+ **/
+s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
+{
+       u32 frctl_reg;
+       u32 rmcs_reg;
+
+       if (packetbuf_num < 0 || packetbuf_num > 7) {
+               hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
+                         " 0-7\n", packetbuf_num);
+       }
+
+       frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+       frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
+
+       rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
+       rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
+
+       /*
+        * 10 gig parts do not have a word in the EEPROM to determine the
+        * default flow control setting, so we explicitly set it to full.
+        */
+       if (hw->fc.type == ixgbe_fc_default)
+               hw->fc.type = ixgbe_fc_full;
+
+       /*
+        * We want to save off the original Flow Control configuration just in
+        * case we get disconnected and then reconnected into a different hub
+        * or switch with different Flow Control capabilities.
+        */
+       hw->fc.original_type = hw->fc.type;
+
+       /*
+        * The possible values of the "flow_control" parameter are:
+        * 0: Flow control is completely disabled
+        * 1: Rx flow control is enabled (we can receive pause frames but not
+        *    send pause frames).
+        * 2: Tx flow control is enabled (we can send pause frames but we do not
+        *    support receiving pause frames)
+        * 3: Both Rx and Tx flow control (symmetric) are enabled.
+        * other: Invalid.
+        */
+       switch (hw->fc.type) {
+       case ixgbe_fc_none:
+               break;
+       case ixgbe_fc_rx_pause:
+               /*
+                * Rx Flow control is enabled,
+                * and Tx Flow control is disabled.
+                */
+               frctl_reg |= IXGBE_FCTRL_RFCE;
+               break;
+       case ixgbe_fc_tx_pause:
+               /*
+                * Tx Flow control is enabled, and Rx Flow control is disabled,
+                * by a software over-ride.
+                */
+               rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
+               break;
+       case ixgbe_fc_full:
+               /*
+                * Flow control (both Rx and Tx) is enabled by a software
+                * over-ride.
+                */
+               frctl_reg |= IXGBE_FCTRL_RFCE;
+               rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
+               break;
+       default:
+               /* We should never get here.  The value should be 0-3. */
+               hw_dbg(hw, "Flow control param set incorrectly\n");
+               break;
+       }
+
+       /* Enable 802.3x based flow control settings. */
+       IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
+       IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
+
+       /*
+        * Check for invalid software configuration, zeros are completely
+        * invalid for all parameters used past this point, and if we enable
+        * flow control with zero water marks, we blast flow control packets.
+        */
+       if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
+               hw_dbg(hw, "Flow control structure initialized incorrectly\n");
+               return IXGBE_ERR_INVALID_LINK_SETTINGS;
+       }
+
+       /*
+        * We need to set up the Receive Threshold high and low water
+        * marks as well as (optionally) enabling the transmission of
+        * XON frames.
+        */
+       if (hw->fc.type & ixgbe_fc_tx_pause) {
+               if (hw->fc.send_xon) {
+                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
+                                       (hw->fc.low_water | IXGBE_FCRTL_XONE));
+               } else {
+                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
+                                       hw->fc.low_water);
+               }
+               IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
+                               (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
+       }
+
+       IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
+       IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+
+       return 0;
+}
+
 /**
  *  ixgbe_setup_mac_link_82598 - Configures MAC link settings
  *  @hw: pointer to hardware structure
@@ -252,8 +357,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
                        }
                        if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) {
                                status = IXGBE_ERR_AUTONEG_NOT_COMPLETE;
-                               hw_dbg(hw,
-                                      "Autonegotiation did not complete.\n");
+                               hw_dbg(hw, "Autonegotiation did not complete.\n");
                        }
                }
        }
@@ -263,8 +367,8 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
         * case we get disconnected and then reconnected into a different hub
         * or switch with different Flow Control capabilities.
         */
-       hw->fc.type = hw->fc.original_type;
-       ixgbe_setup_fc(hw, 0);
+       hw->fc.original_type = hw->fc.type;
+       ixgbe_setup_fc_82598(hw, 0);
 
        /* Add delay to filter out noises during initial link setup */
        msleep(50);
@@ -277,20 +381,35 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
  *  @hw: pointer to hardware structure
  *  @speed: pointer to link speed
  *  @link_up: true is link is up, false otherwise
+ *  @link_up_wait_to_complete: bool used to wait for link up or not
  *
  *  Reads the links register to determine if link is up and the current speed
  **/
-static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
-                                     bool *link_up)
+static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
+                                      ixgbe_link_speed *speed, bool *link_up,
+                                      bool link_up_wait_to_complete)
 {
        u32 links_reg;
+       u32 i;
 
        links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
-
-       if (links_reg & IXGBE_LINKS_UP)
-               *link_up = true;
-       else
-               *link_up = false;
+       if (link_up_wait_to_complete) {
+               for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
+                       if (links_reg & IXGBE_LINKS_UP) {
+                               *link_up = true;
+                               break;
+                       } else {
+                               *link_up = false;
+                       }
+                       msleep(100);
+                       links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS);
+               }
+       } else {
+               if (links_reg & IXGBE_LINKS_UP)
+                       *link_up = true;
+               else
+                       *link_up = false;
+       }
 
        if (links_reg & IXGBE_LINKS_SPEED)
                *speed = IXGBE_LINK_SPEED_10GB_FULL;
@@ -300,6 +419,7 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
        return 0;
 }
 
+
 /**
  *  ixgbe_setup_mac_link_speed_82598 - Set MAC link speed
  *  @hw: pointer to hardware structure
@@ -310,18 +430,18 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed,
  *  Set the link speed in the AUTOC register and restarts link.
  **/
 static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
-                                           u32 speed, bool autoneg,
-                                           bool autoneg_wait_to_complete)
+                                            ixgbe_link_speed speed, bool autoneg,
+                                            bool autoneg_wait_to_complete)
 {
        s32 status = 0;
 
        /* If speed is 10G, then check for CX4 or XAUI. */
        if ((speed == IXGBE_LINK_SPEED_10GB_FULL) &&
-           (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4)))
+           (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) {
                hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
-       else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg))
+       } else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) {
                hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN;
-       else if (autoneg) {
+       else if (autoneg) {
                /* BX mode - Autonegotiate 1G */
                if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD))
                        hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN;
@@ -340,7 +460,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
                 * ixgbe_hw This will write the AUTOC register based on the new
                 * stored values
                 */
-               hw->mac.ops.setup_link(hw);
+               ixgbe_setup_mac_link_82598(hw);
        }
 
        return status;
@@ -358,18 +478,17 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw,
  **/
 static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
 {
-       s32 status = 0;
+       s32 status;
 
        /* Restart autonegotiation on PHY */
-       if (hw->phy.ops.setup_link)
-               status = hw->phy.ops.setup_link(hw);
+       status = hw->phy.ops.setup_link(hw);
 
-       /* Set MAC to KX/KX4 autoneg, which defaultis to Parallel detection */
+       /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
        hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
        hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
 
        /* Set up MAC */
-       hw->mac.ops.setup_link(hw);
+       ixgbe_setup_mac_link_82598(hw);
 
        return status;
 }
@@ -383,23 +502,23 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw)
  *
  *  Sets the link speed in the AUTOC register in the MAC and restarts link.
  **/
-static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
-                                              bool autoneg,
-                                              bool autoneg_wait_to_complete)
+static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
+                                               ixgbe_link_speed speed,
+                                               bool autoneg,
+                                               bool autoneg_wait_to_complete)
 {
-       s32 status = 0;
+       s32 status;
 
        /* Setup the PHY according to input speed */
-       if (hw->phy.ops.setup_link_speed)
-               status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
-                                               autoneg_wait_to_complete);
+       status = hw->phy.ops.setup_link_speed(hw, speed, autoneg,
+                                             autoneg_wait_to_complete);
 
        /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */
        hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX);
        hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN;
 
        /* Set up MAC */
-       hw->mac.ops.setup_link(hw);
+       ixgbe_setup_mac_link_82598(hw);
 
        return status;
 }
@@ -408,7 +527,7 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed,
  *  ixgbe_reset_hw_82598 - Performs hardware reset
  *  @hw: pointer to hardware structure
  *
- *  Resets the hardware by reseting the transmit and receive units, masks and
+ *  Resets the hardware by resetting the transmit and receive units, masks and
  *  clears all interrupts, performing a PHY reset, and performing a link (MAC)
  *  reset.
  **/
@@ -422,35 +541,44 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
        u8  analog_val;
 
        /* Call adapter stop to disable tx/rx and clear interrupts */
-       ixgbe_stop_adapter(hw);
+       hw->mac.ops.stop_adapter(hw);
 
        /*
-        * Power up the Atlas TX lanes if they are currently powered down.
-        * Atlas TX lanes are powered down for MAC loopback tests, but
+        * Power up the Atlas Tx lanes if they are currently powered down.
+        * Atlas Tx lanes are powered down for MAC loopback tests, but
         * they are not automatically restored on reset.
         */
-       ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
+       hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
        if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) {
-               /* Enable TX Atlas so packets can be transmitted again */
-               ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val);
+               /* Enable Tx Atlas so packets can be transmitted again */
+               hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
+                                            &analog_val);
                analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN;
-               ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, analog_val);
+               hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK,
+                                             analog_val);
 
-               ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &analog_val);
+               hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
+                                            &analog_val);
                analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
-               ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, analog_val);
+               hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G,
+                                             analog_val);
 
-               ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &analog_val);
+               hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
+                                            &analog_val);
                analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
-               ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, analog_val);
+               hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G,
+                                             analog_val);
 
-               ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &analog_val);
+               hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
+                                            &analog_val);
                analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
-               ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, analog_val);
+               hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN,
+                                             analog_val);
        }
 
        /* Reset PHY */
-       ixgbe_reset_phy(hw);
+       if (hw->phy.reset_disable == false)
+               hw->phy.ops.reset(hw);
 
        /*
         * Prevent the PCI-E bus from from hanging by disabling PCI-E master
@@ -503,29 +631,311 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
                IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
        } else {
                hw->mac.link_attach_type =
-                                        (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
+                                        (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE);
                hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK);
                hw->mac.link_settings_loaded = true;
        }
 
        /* Store the permanent mac address */
-       ixgbe_get_mac_addr(hw, hw->mac.perm_addr);
+       hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
 
        return status;
 }
 
+/**
+ *  ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address
+ *  @hw: pointer to hardware struct
+ *  @rar: receive address register index to associate with a VMDq index
+ *  @vmdq: VMDq set index
+ **/
+s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+       u32 rar_high;
+
+       rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
+       rar_high &= ~IXGBE_RAH_VIND_MASK;
+       rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK);
+       IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
+       return 0;
+}
+
+/**
+ *  ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address
+ *  @hw: pointer to hardware struct
+ *  @rar: receive address register index to associate with a VMDq index
+ *  @vmdq: VMDq clear index (not used in 82598, but elsewhere)
+ **/
+static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq)
+{
+       u32 rar_high;
+       u32 rar_entries = hw->mac.num_rar_entries;
+
+       if (rar < rar_entries) {
+               rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar));
+               if (rar_high & IXGBE_RAH_VIND_MASK) {
+                       rar_high &= ~IXGBE_RAH_VIND_MASK;
+                       IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high);
+               }
+       } else {
+               hw_dbg(hw, "RAR index %d is out of range.\n", rar);
+       }
+
+       return 0;
+}
+
+/**
+ *  ixgbe_set_vfta_82598 - Set VLAN filter table
+ *  @hw: pointer to hardware structure
+ *  @vlan: VLAN id to write to VLAN filter
+ *  @vind: VMDq output index that maps queue to VLAN id in VFTA
+ *  @vlan_on: boolean flag to turn on/off VLAN in VFTA
+ *
+ *  Turn on/off specified VLAN in the VLAN filter table.
+ **/
+s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind,
+                         bool vlan_on)
+{
+       u32 regindex;
+       u32 bitindex;
+       u32 bits;
+       u32 vftabyte;
+
+       if (vlan > 4095)
+               return IXGBE_ERR_PARAM;
+
+       /* Determine 32-bit word position in array */
+       regindex = (vlan >> 5) & 0x7F;   /* upper seven bits */
+
+       /* Determine the location of the (VMD) queue index */
+       vftabyte =  ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
+       bitindex = (vlan & 0x7) << 2;    /* lower 3 bits indicate nibble */
+
+       /* Set the nibble for VMD queue index */
+       bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex));
+       bits &= (~(0x0F << bitindex));
+       bits |= (vind << bitindex);
+       IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits);
+
+       /* Determine the location of the bit for this VLAN id */
+       bitindex = vlan & 0x1F;   /* lower five bits */
+
+       bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex));
+       if (vlan_on)
+               /* Turn on this VLAN id */
+               bits |= (1 << bitindex);
+       else
+               /* Turn off this VLAN id */
+               bits &= ~(1 << bitindex);
+       IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_clear_vfta_82598 - Clear VLAN filter table
+ *  @hw: pointer to hardware structure
+ *
+ *  Clears the VLAN filer table, and the VMDq index associated with the filter
+ **/
+static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw)
+{
+       u32 offset;
+       u32 vlanbyte;
+
+       for (offset = 0; offset < hw->mac.vft_size; offset++)
+               IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+
+       for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
+               for (offset = 0; offset < hw->mac.vft_size; offset++)
+                       IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
+                                       0);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_blink_led_start_82598 - Blink LED based on index.
+ *  @hw: pointer to hardware structure
+ *  @index: led number to blink
+ **/
+static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index)
+{
+       ixgbe_link_speed speed = 0;
+       bool link_up = 0;
+       u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+       /*
+        * Link must be up to auto-blink the LEDs on the 82598EB MAC;
+        * force it if link is down.
+        */
+       hw->mac.ops.check_link(hw, &speed, &link_up, false);
+
+       if (!link_up) {
+               autoc_reg |= IXGBE_AUTOC_FLU;
+               IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+               msleep(10);
+       }
+
+       led_reg &= ~IXGBE_LED_MODE_MASK(index);
+       led_reg |= IXGBE_LED_BLINK(index);
+       IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+       IXGBE_WRITE_FLUSH(hw);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_blink_led_stop_82598 - Stop blinking LED based on index.
+ *  @hw: pointer to hardware structure
+ *  @index: led number to stop blinking
+ **/
+static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index)
+{
+       u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+
+       autoc_reg &= ~IXGBE_AUTOC_FLU;
+       autoc_reg |= IXGBE_AUTOC_AN_RESTART;
+       IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
+
+       led_reg &= ~IXGBE_LED_MODE_MASK(index);
+       led_reg &= ~IXGBE_LED_BLINK(index);
+       led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
+       IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
+       IXGBE_WRITE_FLUSH(hw);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register
+ *  @hw: pointer to hardware structure
+ *  @reg: analog register to read
+ *  @val: read value
+ *
+ *  Performs read operation to Atlas analog register specified.
+ **/
+s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val)
+{
+       u32  atlas_ctl;
+
+       IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
+                       IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(10);
+       atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
+       *val = (u8)atlas_ctl;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register
+ *  @hw: pointer to hardware structure
+ *  @reg: atlas register to write
+ *  @val: value to write
+ *
+ *  Performs write operation to Atlas analog register specified.
+ **/
+s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val)
+{
+       u32  atlas_ctl;
+
+       atlas_ctl = (reg << 8) | val;
+       IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(10);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_get_supported_physical_layer_82598 - Returns physical layer type
+ *  @hw: pointer to hardware structure
+ *
+ *  Determines physical layer capabilities of the current configuration.
+ **/
+s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
+{
+       s32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+
+       switch (hw->device_id) {
+       case IXGBE_DEV_ID_82598EB_CX4:
+       case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+               break;
+       case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+       case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+               break;
+       case IXGBE_DEV_ID_82598EB_XF_LR:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+               break;
+
+       default:
+               physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+               break;
+       }
+
+       return physical_layer;
+}
+
 static struct ixgbe_mac_operations mac_ops_82598 = {
-       .reset                  = &ixgbe_reset_hw_82598,
+       .init_hw                = &ixgbe_init_hw_generic,
+       .reset_hw               = &ixgbe_reset_hw_82598,
+       .start_hw               = &ixgbe_start_hw_generic,
+       .clear_hw_cntrs         = &ixgbe_clear_hw_cntrs_generic,
        .get_media_type         = &ixgbe_get_media_type_82598,
+       .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598,
+       .get_mac_addr           = &ixgbe_get_mac_addr_generic,
+       .stop_adapter           = &ixgbe_stop_adapter_generic,
+       .read_analog_reg8       = &ixgbe_read_analog_reg8_82598,
+       .write_analog_reg8      = &ixgbe_write_analog_reg8_82598,
        .setup_link             = &ixgbe_setup_mac_link_82598,
-       .check_link             = &ixgbe_check_mac_link_82598,
        .setup_link_speed       = &ixgbe_setup_mac_link_speed_82598,
-       .get_link_settings      = &ixgbe_get_link_settings_82598,
+       .check_link             = &ixgbe_check_mac_link_82598,
+       .get_link_capabilities  = &ixgbe_get_link_capabilities_82598,
+       .led_on                 = &ixgbe_led_on_generic,
+       .led_off                = &ixgbe_led_off_generic,
+       .blink_led_start        = &ixgbe_blink_led_start_82598,
+       .blink_led_stop         = &ixgbe_blink_led_stop_82598,
+       .set_rar                = &ixgbe_set_rar_generic,
+       .clear_rar              = &ixgbe_clear_rar_generic,
+       .set_vmdq               = &ixgbe_set_vmdq_82598,
+       .clear_vmdq             = &ixgbe_clear_vmdq_82598,
+       .init_rx_addrs          = &ixgbe_init_rx_addrs_generic,
+       .update_uc_addr_list    = &ixgbe_update_uc_addr_list_generic,
+       .update_mc_addr_list    = &ixgbe_update_mc_addr_list_generic,
+       .enable_mc              = &ixgbe_enable_mc_generic,
+       .disable_mc             = &ixgbe_disable_mc_generic,
+       .clear_vfta             = &ixgbe_clear_vfta_82598,
+       .set_vfta               = &ixgbe_set_vfta_82598,
+       .setup_fc               = &ixgbe_setup_fc_82598,
+};
+
+static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
+       .init_params            = &ixgbe_init_eeprom_params_generic,
+       .read                   = &ixgbe_read_eeprom_generic,
+       .validate_checksum      = &ixgbe_validate_eeprom_checksum_generic,
+       .update_checksum        = &ixgbe_update_eeprom_checksum_generic,
+};
+
+static struct ixgbe_phy_operations phy_ops_82598 = {
+       .identify               = &ixgbe_identify_phy_generic,
+       /* .identify_sfp        = &ixgbe_identify_sfp_module_generic, */
+       .reset                  = &ixgbe_reset_phy_generic,
+       .read_reg               = &ixgbe_read_phy_reg_generic,
+       .write_reg              = &ixgbe_write_phy_reg_generic,
+       .setup_link             = &ixgbe_setup_phy_link_generic,
+       .setup_link_speed       = &ixgbe_setup_phy_link_speed_generic,
 };
 
 struct ixgbe_info ixgbe_82598_info = {
        .mac                    = ixgbe_mac_82598EB,
        .get_invariants         = &ixgbe_get_invariants_82598,
        .mac_ops                = &mac_ops_82598,
+       .eeprom_ops             = &eeprom_ops_82598,
+       .phy_ops                = &phy_ops_82598,
 };
 
index 9c0d0a1964ebac9508fcdde6a1384eebe27020ca..f67c68404bb382462662ea664749b080a280ab6a 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
 
-static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw);
-
 static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw);
+static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw);
 static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw);
 static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw);
+static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw);
+static void ixgbe_standby_eeprom(struct ixgbe_hw *hw);
+static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
+                                        u16 count);
+static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count);
+static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
+static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec);
+static void ixgbe_release_eeprom(struct ixgbe_hw *hw);
 static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw);
 
-static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw);
-static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw);
+static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index);
+static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index);
 static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr);
 static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
+static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq);
 
 /**
- *  ixgbe_start_hw - Prepare hardware for TX/RX
+ *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
  *  @hw: pointer to hardware structure
  *
  *  Starts the hardware by filling the bus info structure and media type, clears
@@ -54,7 +61,7 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr);
  *  table, VLAN filter table, calls routine to set up link and flow control
  *  settings, and leaves transmit and receive units disabled and uninitialized
  **/
-s32 ixgbe_start_hw(struct ixgbe_hw *hw)
+s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
 {
        u32 ctrl_ext;
 
@@ -62,22 +69,22 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
        hw->phy.media_type = hw->mac.ops.get_media_type(hw);
 
        /* Identify the PHY */
-       ixgbe_identify_phy(hw);
+       hw->phy.ops.identify(hw);
 
        /*
         * Store MAC address from RAR0, clear receive address registers, and
         * clear the multicast table
         */
-       ixgbe_init_rx_addrs(hw);
+       hw->mac.ops.init_rx_addrs(hw);
 
        /* Clear the VLAN filter table */
-       ixgbe_clear_vfta(hw);
+       hw->mac.ops.clear_vfta(hw);
 
        /* Set up link */
        hw->mac.ops.setup_link(hw);
 
        /* Clear statistics registers */
-       ixgbe_clear_hw_cntrs(hw);
+       hw->mac.ops.clear_hw_cntrs(hw);
 
        /* Set No Snoop Disable */
        ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
@@ -92,34 +99,34 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_init_hw - Generic hardware initialization
+ *  ixgbe_init_hw_generic - Generic hardware initialization
  *  @hw: pointer to hardware structure
  *
- *  Initialize the hardware by reseting the hardware, filling the bus info
+ *  Initialize the hardware by resetting the hardware, filling the bus info
  *  structure and media type, clears all on chip counters, initializes receive
  *  address registers, multicast table, VLAN filter table, calls routine to set
  *  up link and flow control settings, and leaves transmit and receive units
  *  disabled and uninitialized
  **/
-s32 ixgbe_init_hw(struct ixgbe_hw *hw)
+s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
 {
        /* Reset the hardware */
-       hw->mac.ops.reset(hw);
+       hw->mac.ops.reset_hw(hw);
 
        /* Start the HW */
-       ixgbe_start_hw(hw);
+       hw->mac.ops.start_hw(hw);
 
        return 0;
 }
 
 /**
- *  ixgbe_clear_hw_cntrs - Generic clear hardware counters
+ *  ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters
  *  @hw: pointer to hardware structure
  *
  *  Clears all hardware statistics counters by reading them from the hardware
  *  Statistics counters are clear on read.
  **/
-static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
+s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw)
 {
        u16 i = 0;
 
@@ -191,7 +198,36 @@ static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_get_mac_addr - Generic get MAC address
+ *  ixgbe_read_pba_num_generic - Reads part number from EEPROM
+ *  @hw: pointer to hardware structure
+ *  @pba_num: stores the part number from the EEPROM
+ *
+ *  Reads the part number from the EEPROM.
+ **/
+s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num)
+{
+       s32 ret_val;
+       u16 data;
+
+       ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data);
+       if (ret_val) {
+               hw_dbg(hw, "NVM Read Error\n");
+               return ret_val;
+       }
+       *pba_num = (u32)(data << 16);
+
+       ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data);
+       if (ret_val) {
+               hw_dbg(hw, "NVM Read Error\n");
+               return ret_val;
+       }
+       *pba_num |= data;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_get_mac_addr_generic - Generic get MAC address
  *  @hw: pointer to hardware structure
  *  @mac_addr: Adapter MAC address
  *
@@ -199,7 +235,7 @@ static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw)
  *  A reset of the adapter must be performed prior to calling this function
  *  in order for the MAC address to have been loaded from the EEPROM into RAR0
  **/
-s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr)
+s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr)
 {
        u32 rar_high;
        u32 rar_low;
@@ -217,30 +253,8 @@ s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr)
        return 0;
 }
 
-s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num)
-{
-       s32 ret_val;
-       u16 data;
-
-       ret_val = ixgbe_read_eeprom(hw, IXGBE_PBANUM0_PTR, &data);
-       if (ret_val) {
-               hw_dbg(hw, "NVM Read Error\n");
-               return ret_val;
-       }
-       *part_num = (u32)(data << 16);
-
-       ret_val = ixgbe_read_eeprom(hw, IXGBE_PBANUM1_PTR, &data);
-       if (ret_val) {
-               hw_dbg(hw, "NVM Read Error\n");
-               return ret_val;
-       }
-       *part_num |= data;
-
-       return 0;
-}
-
 /**
- *  ixgbe_stop_adapter - Generic stop TX/RX units
+ *  ixgbe_stop_adapter_generic - Generic stop Tx/Rx units
  *  @hw: pointer to hardware structure
  *
  *  Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts,
@@ -248,7 +262,7 @@ s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num)
  *  the shared code and drivers to determine if the adapter is in a stopped
  *  state and should not touch the hardware.
  **/
-s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
+s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw)
 {
        u32 number_of_queues;
        u32 reg_val;
@@ -264,6 +278,7 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
        reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
        reg_val &= ~(IXGBE_RXCTRL_RXEN);
        IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val);
+       IXGBE_WRITE_FLUSH(hw);
        msleep(2);
 
        /* Clear interrupt mask to stop from interrupts being generated */
@@ -273,7 +288,7 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
        IXGBE_READ_REG(hw, IXGBE_EICR);
 
        /* Disable the transmit unit.  Each queue must be disabled. */
-       number_of_queues = hw->mac.num_tx_queues;
+       number_of_queues = hw->mac.max_tx_queues;
        for (i = 0; i < number_of_queues; i++) {
                reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i));
                if (reg_val & IXGBE_TXDCTL_ENABLE) {
@@ -282,15 +297,22 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw)
                }
        }
 
+       /*
+        * Prevent the PCI-E bus from from hanging by disabling PCI-E master
+        * access and verify no pending requests
+        */
+       if (ixgbe_disable_pcie_master(hw) != 0)
+               hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
+
        return 0;
 }
 
 /**
- *  ixgbe_led_on - Turns on the software controllable LEDs.
+ *  ixgbe_led_on_generic - Turns on the software controllable LEDs.
  *  @hw: pointer to hardware structure
  *  @index: led number to turn on
  **/
-s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
+s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
 {
        u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
 
@@ -304,11 +326,11 @@ s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index)
 }
 
 /**
- *  ixgbe_led_off - Turns off the software controllable LEDs.
+ *  ixgbe_led_off_generic - Turns off the software controllable LEDs.
  *  @hw: pointer to hardware structure
  *  @index: led number to turn off
  **/
-s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
+s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
 {
        u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
 
@@ -321,15 +343,14 @@ s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index)
        return 0;
 }
 
-
 /**
- *  ixgbe_init_eeprom - Initialize EEPROM params
+ *  ixgbe_init_eeprom_params_generic - Initialize EEPROM params
  *  @hw: pointer to hardware structure
  *
  *  Initializes the EEPROM parameters ixgbe_eeprom_info within the
  *  ixgbe_hw struct in order to set up EEPROM access.
  **/
-s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
+s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw)
 {
        struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
        u32 eec;
@@ -337,6 +358,9 @@ s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
 
        if (eeprom->type == ixgbe_eeprom_uninitialized) {
                eeprom->type = ixgbe_eeprom_none;
+               /* Set default semaphore delay to 10ms which is a well
+                * tested value */
+               eeprom->semaphore_delay = 10;
 
                /*
                 * Check for EEPROM present first.
@@ -369,18 +393,85 @@ s32 ixgbe_init_eeprom(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_read_eeprom - Read EEPROM word using EERD
+ *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ *  @hw: pointer to hardware structure
+ *  @offset: offset within the EEPROM to be read
+ *  @data: read 16 bit value from EEPROM
+ *
+ *  Reads 16 bit value from EEPROM through bit-bang method
+ **/
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+                                       u16 *data)
+{
+       s32 status;
+       u16 word_in;
+       u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+
+       hw->eeprom.ops.init_params(hw);
+
+       if (offset >= hw->eeprom.word_size) {
+               status = IXGBE_ERR_EEPROM;
+               goto out;
+       }
+
+       /* Prepare the EEPROM for reading  */
+       status = ixgbe_acquire_eeprom(hw);
+
+       if (status == 0) {
+               if (ixgbe_ready_eeprom(hw) != 0) {
+                       ixgbe_release_eeprom(hw);
+                       status = IXGBE_ERR_EEPROM;
+               }
+       }
+
+       if (status == 0) {
+               ixgbe_standby_eeprom(hw);
+
+               /*
+                * Some SPI eeproms use the 8th address bit embedded in the
+                * opcode
+                */
+               if ((hw->eeprom.address_bits == 8) && (offset >= 128))
+                       read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+
+               /* Send the READ command (opcode + addr) */
+               ixgbe_shift_out_eeprom_bits(hw, read_opcode,
+                                           IXGBE_EEPROM_OPCODE_BITS);
+               ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
+                                           hw->eeprom.address_bits);
+
+               /* Read the data. */
+               word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
+               *data = (word_in >> 8) | (word_in << 8);
+
+               /* End this read operation */
+               ixgbe_release_eeprom(hw);
+       }
+
+out:
+       return status;
+}
+
+/**
+ *  ixgbe_read_eeprom_generic - Read EEPROM word using EERD
  *  @hw: pointer to hardware structure
  *  @offset: offset of  word in the EEPROM to read
  *  @data: word read from the EEPROM
  *
  *  Reads a 16 bit word from the EEPROM using the EERD register.
  **/
-s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data)
+s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
 {
        u32 eerd;
        s32 status;
 
+       hw->eeprom.ops.init_params(hw);
+
+       if (offset >= hw->eeprom.word_size) {
+               status = IXGBE_ERR_EEPROM;
+               goto out;
+       }
+
        eerd = (offset << IXGBE_EEPROM_READ_ADDR_SHIFT) +
               IXGBE_EEPROM_READ_REG_START;
 
@@ -389,10 +480,11 @@ s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data)
 
        if (status == 0)
                *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
-                       IXGBE_EEPROM_READ_REG_DATA);
+                        IXGBE_EEPROM_READ_REG_DATA);
        else
                hw_dbg(hw, "Eeprom read timed out\n");
 
+out:
        return status;
 }
 
@@ -419,6 +511,58 @@ static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw)
        return status;
 }
 
+/**
+ *  ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang
+ *  @hw: pointer to hardware structure
+ *
+ *  Prepares EEPROM for access using bit-bang method. This function should
+ *  be called before issuing a command to the EEPROM.
+ **/
+static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw)
+{
+       s32 status = 0;
+       u32 eec;
+       u32 i;
+
+       if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0)
+               status = IXGBE_ERR_SWFW_SYNC;
+
+       if (status == 0) {
+               eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+               /* Request EEPROM Access */
+               eec |= IXGBE_EEC_REQ;
+               IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+
+               for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) {
+                       eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+                       if (eec & IXGBE_EEC_GNT)
+                               break;
+                       udelay(5);
+               }
+
+               /* Release if grant not acquired */
+               if (!(eec & IXGBE_EEC_GNT)) {
+                       eec &= ~IXGBE_EEC_REQ;
+                       IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+                       hw_dbg(hw, "Could not acquire EEPROM grant\n");
+
+                       ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+                       status = IXGBE_ERR_EEPROM;
+               }
+       }
+
+       /* Setup EEPROM for Read/Write */
+       if (status == 0) {
+               /* Clear CS and SK */
+               eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK);
+               IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+               IXGBE_WRITE_FLUSH(hw);
+               udelay(1);
+       }
+       return status;
+}
+
 /**
  *  ixgbe_get_eeprom_semaphore - Get hardware semaphore
  *  @hw: pointer to hardware structure
@@ -475,7 +619,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw)
                 */
                if (i >= timeout) {
                        hw_dbg(hw, "Driver can't access the Eeprom - Semaphore "
-                                "not granted.\n");
+                              "not granted.\n");
                        ixgbe_release_eeprom_semaphore(hw);
                        status = IXGBE_ERR_EEPROM;
                }
@@ -502,6 +646,217 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw)
        IXGBE_WRITE_FLUSH(hw);
 }
 
+/**
+ *  ixgbe_ready_eeprom - Polls for EEPROM ready
+ *  @hw: pointer to hardware structure
+ **/
+static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw)
+{
+       s32 status = 0;
+       u16 i;
+       u8 spi_stat_reg;
+
+       /*
+        * Read "Status Register" repeatedly until the LSB is cleared.  The
+        * EEPROM will signal that the command has been completed by clearing
+        * bit 0 of the internal status register.  If it's not cleared within
+        * 5 milliseconds, then error out.
+        */
+       for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) {
+               ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI,
+                                           IXGBE_EEPROM_OPCODE_BITS);
+               spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8);
+               if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI))
+                       break;
+
+               udelay(5);
+               ixgbe_standby_eeprom(hw);
+       };
+
+       /*
+        * On some parts, SPI write time could vary from 0-20mSec on 3.3V
+        * devices (and only 0-5mSec on 5V devices)
+        */
+       if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) {
+               hw_dbg(hw, "SPI EEPROM Status error\n");
+               status = IXGBE_ERR_EEPROM;
+       }
+
+       return status;
+}
+
+/**
+ *  ixgbe_standby_eeprom - Returns EEPROM to a "standby" state
+ *  @hw: pointer to hardware structure
+ **/
+static void ixgbe_standby_eeprom(struct ixgbe_hw *hw)
+{
+       u32 eec;
+
+       eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+       /* Toggle CS to flush commands */
+       eec |= IXGBE_EEC_CS;
+       IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(1);
+       eec &= ~IXGBE_EEC_CS;
+       IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(1);
+}
+
+/**
+ *  ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM.
+ *  @hw: pointer to hardware structure
+ *  @data: data to send to the EEPROM
+ *  @count: number of bits to shift out
+ **/
+static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data,
+                                        u16 count)
+{
+       u32 eec;
+       u32 mask;
+       u32 i;
+
+       eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+       /*
+        * Mask is used to shift "count" bits of "data" out to the EEPROM
+        * one bit at a time.  Determine the starting bit based on count
+        */
+       mask = 0x01 << (count - 1);
+
+       for (i = 0; i < count; i++) {
+               /*
+                * A "1" is shifted out to the EEPROM by setting bit "DI" to a
+                * "1", and then raising and then lowering the clock (the SK
+                * bit controls the clock input to the EEPROM).  A "0" is
+                * shifted out to the EEPROM by setting "DI" to "0" and then
+                * raising and then lowering the clock.
+                */
+               if (data & mask)
+                       eec |= IXGBE_EEC_DI;
+               else
+                       eec &= ~IXGBE_EEC_DI;
+
+               IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+               IXGBE_WRITE_FLUSH(hw);
+
+               udelay(1);
+
+               ixgbe_raise_eeprom_clk(hw, &eec);
+               ixgbe_lower_eeprom_clk(hw, &eec);
+
+               /*
+                * Shift mask to signify next bit of data to shift in to the
+                * EEPROM
+                */
+               mask = mask >> 1;
+       };
+
+       /* We leave the "DI" bit set to "0" when we leave this routine. */
+       eec &= ~IXGBE_EEC_DI;
+       IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+       IXGBE_WRITE_FLUSH(hw);
+}
+
+/**
+ *  ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM
+ *  @hw: pointer to hardware structure
+ **/
+static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count)
+{
+       u32 eec;
+       u32 i;
+       u16 data = 0;
+
+       /*
+        * In order to read a register from the EEPROM, we need to shift
+        * 'count' bits in from the EEPROM. Bits are "shifted in" by raising
+        * the clock input to the EEPROM (setting the SK bit), and then reading
+        * the value of the "DO" bit.  During this "shifting in" process the
+        * "DI" bit should always be clear.
+        */
+       eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+       eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI);
+
+       for (i = 0; i < count; i++) {
+               data = data << 1;
+               ixgbe_raise_eeprom_clk(hw, &eec);
+
+               eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+               eec &= ~(IXGBE_EEC_DI);
+               if (eec & IXGBE_EEC_DO)
+                       data |= 1;
+
+               ixgbe_lower_eeprom_clk(hw, &eec);
+       }
+
+       return data;
+}
+
+/**
+ *  ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input.
+ *  @hw: pointer to hardware structure
+ *  @eec: EEC register's current value
+ **/
+static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
+{
+       /*
+        * Raise the clock input to the EEPROM
+        * (setting the SK bit), then delay
+        */
+       *eec = *eec | IXGBE_EEC_SK;
+       IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(1);
+}
+
+/**
+ *  ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input.
+ *  @hw: pointer to hardware structure
+ *  @eecd: EECD's current value
+ **/
+static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec)
+{
+       /*
+        * Lower the clock input to the EEPROM (clearing the SK bit), then
+        * delay
+        */
+       *eec = *eec & ~IXGBE_EEC_SK;
+       IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec);
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(1);
+}
+
+/**
+ *  ixgbe_release_eeprom - Release EEPROM, release semaphores
+ *  @hw: pointer to hardware structure
+ **/
+static void ixgbe_release_eeprom(struct ixgbe_hw *hw)
+{
+       u32 eec;
+
+       eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+
+       eec |= IXGBE_EEC_CS;  /* Pull CS high */
+       eec &= ~IXGBE_EEC_SK; /* Lower SCK */
+
+       IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+       IXGBE_WRITE_FLUSH(hw);
+
+       udelay(1);
+
+       /* Stop requesting EEPROM access */
+       eec &= ~IXGBE_EEC_REQ;
+       IXGBE_WRITE_REG(hw, IXGBE_EEC, eec);
+
+       ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+}
+
 /**
  *  ixgbe_calc_eeprom_checksum - Calculates and returns the checksum
  *  @hw: pointer to hardware structure
@@ -517,7 +872,7 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
 
        /* Include 0x0-0x3F in the checksum */
        for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
-               if (ixgbe_read_eeprom(hw, i, &word) != 0) {
+               if (hw->eeprom.ops.read(hw, i, &word) != 0) {
                        hw_dbg(hw, "EEPROM read failed\n");
                        break;
                }
@@ -526,15 +881,15 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
 
        /* Include all data from pointers except for the fw pointer */
        for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) {
-               ixgbe_read_eeprom(hw, i, &pointer);
+               hw->eeprom.ops.read(hw, i, &pointer);
 
                /* Make sure the pointer seems valid */
                if (pointer != 0xFFFF && pointer != 0) {
-                       ixgbe_read_eeprom(hw, pointer, &length);
+                       hw->eeprom.ops.read(hw, pointer, &length);
 
                        if (length != 0xFFFF && length != 0) {
                                for (j = pointer+1; j <= pointer+length; j++) {
-                                       ixgbe_read_eeprom(hw, j, &word);
+                                       hw->eeprom.ops.read(hw, j, &word);
                                        checksum += word;
                                }
                        }
@@ -547,14 +902,15 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_validate_eeprom_checksum - Validate EEPROM checksum
+ *  ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum
  *  @hw: pointer to hardware structure
  *  @checksum_val: calculated checksum
  *
  *  Performs checksum calculation and validates the EEPROM checksum.  If the
  *  caller does not need checksum_val, the value can be NULL.
  **/
-s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
+s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
+                                           u16 *checksum_val)
 {
        s32 status;
        u16 checksum;
@@ -565,12 +921,12 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
         * not continue or we could be in for a very long wait while every
         * EEPROM read fails
         */
-       status = ixgbe_read_eeprom(hw, 0, &checksum);
+       status = hw->eeprom.ops.read(hw, 0, &checksum);
 
        if (status == 0) {
                checksum = ixgbe_calc_eeprom_checksum(hw);
 
-               ixgbe_read_eeprom(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
+               hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum);
 
                /*
                 * Verify read checksum from EEPROM is the same as
@@ -589,6 +945,33 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val)
        return status;
 }
 
+/**
+ *  ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum
+ *  @hw: pointer to hardware structure
+ **/
+s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw)
+{
+       s32 status;
+       u16 checksum;
+
+       /*
+        * Read the first word from the EEPROM. If this times out or fails, do
+        * not continue or we could be in for a very long wait while every
+        * EEPROM read fails
+        */
+       status = hw->eeprom.ops.read(hw, 0, &checksum);
+
+       if (status == 0) {
+               checksum = ixgbe_calc_eeprom_checksum(hw);
+               status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM,
+                                           checksum);
+       } else {
+               hw_dbg(hw, "EEPROM read failed\n");
+       }
+
+       return status;
+}
+
 /**
  *  ixgbe_validate_mac_addr - Validate MAC address
  *  @mac_addr: pointer to MAC address.
@@ -607,58 +990,137 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr)
                status = IXGBE_ERR_INVALID_MAC_ADDR;
        /* Reject the zero address */
        else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 &&
-                mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0)
+                mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0)
                status = IXGBE_ERR_INVALID_MAC_ADDR;
 
        return status;
 }
 
 /**
- *  ixgbe_set_rar - Set RX address register
+ *  ixgbe_set_rar_generic - Set Rx address register
  *  @hw: pointer to hardware structure
- *  @addr: Address to put into receive address register
  *  @index: Receive address register to write
- *  @vind: Vind to set RAR to
+ *  @addr: Address to put into receive address register
+ *  @vmdq: VMDq "set" or "pool" index
  *  @enable_addr: set flag that address is active
  *
  *  Puts an ethernet address into a receive address register.
  **/
-s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
-                 u32 enable_addr)
+s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
+                          u32 enable_addr)
 {
        u32 rar_low, rar_high;
+       u32 rar_entries = hw->mac.num_rar_entries;
 
-       /*
-        * HW expects these in little endian so we reverse the byte order from
-        * network order (big endian) to little endian
-        */
-       rar_low = ((u32)addr[0] |
-                  ((u32)addr[1] << 8) |
-                  ((u32)addr[2] << 16) |
-                  ((u32)addr[3] << 24));
+       /* setup VMDq pool selection before this RAR gets enabled */
+       hw->mac.ops.set_vmdq(hw, index, vmdq);
 
-       rar_high = ((u32)addr[4] |
-                   ((u32)addr[5] << 8) |
-                   ((vind << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK));
+       /* Make sure we are using a valid rar index range */
+       if (index < rar_entries) {
+               /*
+                * HW expects these in little endian so we reverse the byte
+                * order from network order (big endian) to little endian
+                */
+               rar_low = ((u32)addr[0] |
+                          ((u32)addr[1] << 8) |
+                          ((u32)addr[2] << 16) |
+                          ((u32)addr[3] << 24));
+               /*
+                * Some parts put the VMDq setting in the extra RAH bits,
+                * so save everything except the lower 16 bits that hold part
+                * of the address and the address valid bit.
+                */
+               rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+               rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
+               rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8));
 
-       if (enable_addr != 0)
-               rar_high |= IXGBE_RAH_AV;
+               if (enable_addr != 0)
+                       rar_high |= IXGBE_RAH_AV;
 
-       IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
-       IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+               IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low);
+               IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+       } else {
+               hw_dbg(hw, "RAR index %d is out of range.\n", index);
+       }
 
        return 0;
 }
 
 /**
- *  ixgbe_init_rx_addrs - Initializes receive address filters.
+ *  ixgbe_clear_rar_generic - Remove Rx address register
+ *  @hw: pointer to hardware structure
+ *  @index: Receive address register to write
+ *
+ *  Clears an ethernet address from a receive address register.
+ **/
+s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index)
+{
+       u32 rar_high;
+       u32 rar_entries = hw->mac.num_rar_entries;
+
+       /* Make sure we are using a valid rar index range */
+       if (index < rar_entries) {
+               /*
+                * Some parts put the VMDq setting in the extra RAH bits,
+                * so save everything except the lower 16 bits that hold part
+                * of the address and the address valid bit.
+                */
+               rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+               rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV);
+
+               IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0);
+               IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+       } else {
+               hw_dbg(hw, "RAR index %d is out of range.\n", index);
+       }
+
+       /* clear VMDq pool/queue selection for this RAR */
+       hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_enable_rar - Enable Rx address register
+ *  @hw: pointer to hardware structure
+ *  @index: index into the RAR table
+ *
+ *  Enables the select receive address register.
+ **/
+static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index)
+{
+       u32 rar_high;
+
+       rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+       rar_high |= IXGBE_RAH_AV;
+       IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+}
+
+/**
+ *  ixgbe_disable_rar - Disable Rx address register
+ *  @hw: pointer to hardware structure
+ *  @index: index into the RAR table
+ *
+ *  Disables the select receive address register.
+ **/
+static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index)
+{
+       u32 rar_high;
+
+       rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index));
+       rar_high &= (~IXGBE_RAH_AV);
+       IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high);
+}
+
+/**
+ *  ixgbe_init_rx_addrs_generic - Initializes receive address filters.
  *  @hw: pointer to hardware structure
  *
  *  Places the MAC address in receive address register 0 and clears the rest
- *  of the receive addresss registers. Clears the multicast table. Assumes
+ *  of the receive address registers. Clears the multicast table. Assumes
  *  the receiver is in reset when the routine is called.
  **/
-static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
+s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw)
 {
        u32 i;
        u32 rar_entries = hw->mac.num_rar_entries;
@@ -671,29 +1133,30 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
        if (ixgbe_validate_mac_addr(hw->mac.addr) ==
            IXGBE_ERR_INVALID_MAC_ADDR) {
                /* Get the MAC address from the RAR0 for later reference */
-               ixgbe_get_mac_addr(hw, hw->mac.addr);
+               hw->mac.ops.get_mac_addr(hw, hw->mac.addr);
 
                hw_dbg(hw, " Keeping Current RAR0 Addr =%.2X %.2X %.2X ",
-                         hw->mac.addr[0], hw->mac.addr[1],
-                         hw->mac.addr[2]);
+                      hw->mac.addr[0], hw->mac.addr[1],
+                      hw->mac.addr[2]);
                hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
-                         hw->mac.addr[4], hw->mac.addr[5]);
+                      hw->mac.addr[4], hw->mac.addr[5]);
        } else {
                /* Setup the receive address. */
                hw_dbg(hw, "Overriding MAC Address in RAR[0]\n");
                hw_dbg(hw, " New MAC Addr =%.2X %.2X %.2X ",
-                         hw->mac.addr[0], hw->mac.addr[1],
-                         hw->mac.addr[2]);
+                      hw->mac.addr[0], hw->mac.addr[1],
+                      hw->mac.addr[2]);
                hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3],
-                         hw->mac.addr[4], hw->mac.addr[5]);
+                      hw->mac.addr[4], hw->mac.addr[5]);
 
-               ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
+               hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
        }
+       hw->addr_ctrl.overflow_promisc = 0;
 
        hw->addr_ctrl.rar_used_count = 1;
 
        /* Zero out the other receive addresses. */
-       hw_dbg(hw, "Clearing RAR[1-15]\n");
+       hw_dbg(hw, "Clearing RAR[1-%d]\n", rar_entries - 1);
        for (i = 1; i < rar_entries; i++) {
                IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
                IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
@@ -708,6 +1171,9 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
        for (i = 0; i < hw->mac.mcft_size; i++)
                IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0);
 
+       if (hw->mac.ops.init_uta_tables)
+               hw->mac.ops.init_uta_tables(hw);
+
        return 0;
 }
 
@@ -718,7 +1184,7 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw)
  *
  *  Adds it to unused receive address register or goes into promiscuous mode.
  **/
-void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
+static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
 {
        u32 rar_entries = hw->mac.num_rar_entries;
        u32 rar;
@@ -733,7 +1199,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
        if (hw->addr_ctrl.rar_used_count < rar_entries) {
                rar = hw->addr_ctrl.rar_used_count -
                      hw->addr_ctrl.mc_addr_in_rar_count;
-               ixgbe_set_rar(hw, rar, addr, 0, IXGBE_RAH_AV);
+               hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV);
                hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar);
                hw->addr_ctrl.rar_used_count++;
        } else {
@@ -744,7 +1210,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
 }
 
 /**
- *  ixgbe_update_uc_addr_list - Updates MAC list of secondary addresses
+ *  ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses
  *  @hw: pointer to hardware structure
  *  @addr_list: the list of new addresses
  *  @addr_count: number of addresses
@@ -757,7 +1223,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr)
  *  Drivers using secondary unicast addresses must set user_set_promisc when
  *  manually putting the device into promiscuous mode.
  **/
-s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
                               u32 addr_count, ixgbe_mc_addr_itr next)
 {
        u8 *addr;
@@ -787,7 +1253,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
        for (i = 0; i < addr_count; i++) {
                hw_dbg(hw, " Adding the secondary addresses:\n");
                addr = next(hw, &addr_list, &vmdq);
-               ixgbe_add_uc_addr(hw, addr);
+               ixgbe_add_uc_addr(hw, addr, vmdq);
        }
 
        if (hw->addr_ctrl.overflow_promisc) {
@@ -808,7 +1274,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
                }
        }
 
-       hw_dbg(hw, "ixgbe_update_uc_addr_list Complete\n");
+       hw_dbg(hw, "ixgbe_update_uc_addr_list_generic Complete\n");
        return 0;
 }
 
@@ -821,7 +1287,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list,
  *  bit-vector to set in the multicast table. The hardware uses 12 bits, from
  *  incoming rx multicast addresses, to determine the bit-vector to check in
  *  the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set
- *  by the MO field of the MCSTCTRL. The MO field is set during initalization
+ *  by the MO field of the MCSTCTRL. The MO field is set during initialization
  *  to mc_filter_type.
  **/
 static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
@@ -829,19 +1295,19 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr)
        u32 vector = 0;
 
        switch (hw->mac.mc_filter_type) {
-       case 0:   /* use bits [47:36] of the address */
+       case 0:   /* use bits [47:36] of the address */
                vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4));
                break;
-       case 1:   /* use bits [46:35] of the address */
+       case 1:   /* use bits [46:35] of the address */
                vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5));
                break;
-       case 2:   /* use bits [45:34] of the address */
+       case 2:   /* use bits [45:34] of the address */
                vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6));
                break;
-       case 3:   /* use bits [43:32] of the address */
+       case 3:   /* use bits [43:32] of the address */
                vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8));
                break;
-       default:         /* Invalid mc_filter_type */
+       default:  /* Invalid mc_filter_type */
                hw_dbg(hw, "MC filter type param set incorrectly\n");
                break;
        }
@@ -896,20 +1362,21 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr)
 static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
 {
        u32 rar_entries = hw->mac.num_rar_entries;
+       u32 rar;
 
        hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n",
-                 mc_addr[0], mc_addr[1], mc_addr[2],
-                 mc_addr[3], mc_addr[4], mc_addr[5]);
+              mc_addr[0], mc_addr[1], mc_addr[2],
+              mc_addr[3], mc_addr[4], mc_addr[5]);
 
        /*
         * Place this multicast address in the RAR if there is room,
         * else put it in the MTA
         */
        if (hw->addr_ctrl.rar_used_count < rar_entries) {
-               ixgbe_set_rar(hw, hw->addr_ctrl.rar_used_count,
-                             mc_addr, 0, IXGBE_RAH_AV);
-               hw_dbg(hw, "Added a multicast address to RAR[%d]\n",
-                         hw->addr_ctrl.rar_used_count);
+               /* use RAR from the end up for multicast */
+               rar = rar_entries - hw->addr_ctrl.mc_addr_in_rar_count - 1;
+               hw->mac.ops.set_rar(hw, rar, mc_addr, 0, IXGBE_RAH_AV);
+               hw_dbg(hw, "Added a multicast address to RAR[%d]\n", rar);
                hw->addr_ctrl.rar_used_count++;
                hw->addr_ctrl.mc_addr_in_rar_count++;
        } else {
@@ -920,19 +1387,19 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr)
 }
 
 /**
- *  ixgbe_update_mc_addr_list - Updates MAC list of multicast addresses
+ *  ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses
  *  @hw: pointer to hardware structure
  *  @mc_addr_list: the list of new multicast addresses
  *  @mc_addr_count: number of addresses
  *  @next: iterator function to walk the multicast address list
  *
  *  The given list replaces any existing list. Clears the MC addrs from receive
- *  address registers and the multicast table. Uses unsed receive address
+ *  address registers and the multicast table. Uses unused receive address
  *  registers for the first multicast addresses, and hashes the rest into the
  *  multicast table.
  **/
-s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
-                             u32 mc_addr_count, ixgbe_mc_addr_itr next)
+s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
+                                      u32 mc_addr_count, ixgbe_mc_addr_itr next)
 {
        u32 i;
        u32 rar_entries = hw->mac.num_rar_entries;
@@ -948,7 +1415,8 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
        hw->addr_ctrl.mta_in_use = 0;
 
        /* Zero out the other receive addresses. */
-       hw_dbg(hw, "Clearing RAR[1-15]\n");
+       hw_dbg(hw, "Clearing RAR[%d-%d]\n", hw->addr_ctrl.rar_used_count,
+                 rar_entries - 1);
        for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) {
                IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0);
                IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0);
@@ -968,190 +1436,55 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
        /* Enable mta */
        if (hw->addr_ctrl.mta_in_use > 0)
                IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL,
-                               IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
+                               IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type);
 
-       hw_dbg(hw, "ixgbe_update_mc_addr_list Complete\n");
+       hw_dbg(hw, "ixgbe_update_mc_addr_list_generic Complete\n");
        return 0;
 }
 
 /**
- *  ixgbe_clear_vfta - Clear VLAN filter table
+ *  ixgbe_enable_mc_generic - Enable multicast address in RAR
  *  @hw: pointer to hardware structure
  *
- *  Clears the VLAN filer table, and the VMDq index associated with the filter
+ *  Enables multicast address in RAR and the use of the multicast hash table.
  **/
-static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw)
+s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw)
 {
-       u32 offset;
-       u32 vlanbyte;
+       u32 i;
+       u32 rar_entries = hw->mac.num_rar_entries;
+       struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
 
-       for (offset = 0; offset < hw->mac.vft_size; offset++)
-               IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0);
+       if (a->mc_addr_in_rar_count > 0)
+               for (i = (rar_entries - a->mc_addr_in_rar_count);
+                    i < rar_entries; i++)
+                       ixgbe_enable_rar(hw, i);
 
-       for (vlanbyte = 0; vlanbyte < 4; vlanbyte++)
-               for (offset = 0; offset < hw->mac.vft_size; offset++)
-                       IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset),
-                                       0);
+       if (a->mta_in_use > 0)
+               IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE |
+                               hw->mac.mc_filter_type);
 
        return 0;
 }
 
 /**
- *  ixgbe_set_vfta - Set VLAN filter table
+ *  ixgbe_disable_mc_generic - Disable multicast address in RAR
  *  @hw: pointer to hardware structure
- *  @vlan: VLAN id to write to VLAN filter
- *  @vind: VMDq output index that maps queue to VLAN id in VFTA
- *  @vlan_on: boolean flag to turn on/off VLAN in VFTA
  *
- *  Turn on/off specified VLAN in the VLAN filter table.
+ *  Disables multicast address in RAR and the use of the multicast hash table.
  **/
-s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind,
-                  bool vlan_on)
+s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
 {
-       u32 VftaIndex;
-       u32 BitOffset;
-       u32 VftaReg;
-       u32 VftaByte;
-
-       /* Determine 32-bit word position in array */
-       VftaIndex = (vlan >> 5) & 0x7F;   /* upper seven bits */
-
-       /* Determine the location of the (VMD) queue index */
-       VftaByte =  ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */
-       BitOffset = (vlan & 0x7) << 2;    /* lower 3 bits indicate nibble */
-
-       /* Set the nibble for VMD queue index */
-       VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex));
-       VftaReg &= (~(0x0F << BitOffset));
-       VftaReg |= (vind << BitOffset);
-       IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex), VftaReg);
-
-       /* Determine the location of the bit for this VLAN id */
-       BitOffset = vlan & 0x1F;           /* lower five bits */
-
-       VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTA(VftaIndex));
-       if (vlan_on)
-               /* Turn on this VLAN id */
-               VftaReg |= (1 << BitOffset);
-       else
-               /* Turn off this VLAN id */
-               VftaReg &= ~(1 << BitOffset);
-       IXGBE_WRITE_REG(hw, IXGBE_VFTA(VftaIndex), VftaReg);
-
-       return 0;
-}
-
-/**
- *  ixgbe_setup_fc - Configure flow control settings
- *  @hw: pointer to hardware structure
- *  @packetbuf_num: packet buffer number (0-7)
- *
- *  Configures the flow control settings based on SW configuration.
- *  This function is used for 802.3x flow control configuration only.
- **/
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
-{
-       u32 frctl_reg;
-       u32 rmcs_reg;
-
-       if (packetbuf_num < 0 || packetbuf_num > 7)
-               hw_dbg(hw, "Invalid packet buffer number [%d], expected range "
-                      "is 0-7\n", packetbuf_num);
-
-       frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-       frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
-
-       rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
-       rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X);
-
-       /*
-        * 10 gig parts do not have a word in the EEPROM to determine the
-        * default flow control setting, so we explicitly set it to full.
-        */
-       if (hw->fc.type == ixgbe_fc_default)
-               hw->fc.type = ixgbe_fc_full;
-
-       /*
-        * We want to save off the original Flow Control configuration just in
-        * case we get disconnected and then reconnected into a different hub
-        * or switch with different Flow Control capabilities.
-        */
-       hw->fc.type = hw->fc.original_type;
-
-       /*
-        * The possible values of the "flow_control" parameter are:
-        * 0: Flow control is completely disabled
-        * 1: Rx flow control is enabled (we can receive pause frames but not
-        *    send pause frames).
-        * 2: Tx flow control is enabled (we can send pause frames but we do not
-        *    support receiving pause frames)
-        * 3: Both Rx and TX flow control (symmetric) are enabled.
-        * other: Invalid.
-        */
-       switch (hw->fc.type) {
-       case ixgbe_fc_none:
-               break;
-       case ixgbe_fc_rx_pause:
-               /*
-                * RX Flow control is enabled,
-                * and TX Flow control is disabled.
-                */
-               frctl_reg |= IXGBE_FCTRL_RFCE;
-               break;
-       case ixgbe_fc_tx_pause:
-               /*
-                * TX Flow control is enabled, and RX Flow control is disabled,
-                * by a software over-ride.
-                */
-               rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
-               break;
-       case ixgbe_fc_full:
-               /*
-                * Flow control (both RX and TX) is enabled by a software
-                * over-ride.
-                */
-               frctl_reg |= IXGBE_FCTRL_RFCE;
-               rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
-               break;
-       default:
-               /* We should never get here.  The value should be 0-3. */
-               hw_dbg(hw, "Flow control param set incorrectly\n");
-               break;
-       }
+       u32 i;
+       u32 rar_entries = hw->mac.num_rar_entries;
+       struct ixgbe_addr_filter_info *a = &hw->addr_ctrl;
 
-       /* Enable 802.3x based flow control settings. */
-       IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg);
-       IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
+       if (a->mc_addr_in_rar_count > 0)
+               for (i = (rar_entries - a->mc_addr_in_rar_count);
+                    i < rar_entries; i++)
+                       ixgbe_disable_rar(hw, i);
 
-       /*
-        * Check for invalid software configuration, zeros are completely
-        * invalid for all parameters used past this point, and if we enable
-        * flow control with zero water marks, we blast flow control packets.
-        */
-       if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
-               hw_dbg(hw, "Flow control structure initialized incorrectly\n");
-               return IXGBE_ERR_INVALID_LINK_SETTINGS;
-       }
-
-       /*
-        * We need to set up the Receive Threshold high and low water
-        * marks as well as (optionally) enabling the transmission of
-        * XON frames.
-        */
-       if (hw->fc.type & ixgbe_fc_tx_pause) {
-               if (hw->fc.send_xon) {
-                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
-                                       (hw->fc.low_water | IXGBE_FCRTL_XONE));
-               } else {
-                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num),
-                                       hw->fc.low_water);
-               }
-               IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num),
-                               (hw->fc.high_water)|IXGBE_FCRTH_FCEN);
-       }
-
-       IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time);
-       IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1));
+       if (a->mta_in_use > 0)
+               IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type);
 
        return 0;
 }
@@ -1167,13 +1500,24 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
  **/
 s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
 {
-       u32 ctrl;
-       s32 i;
+       u32 i;
+       u32 reg_val;
+       u32 number_of_queues;
        s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
 
-       ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL);
-       ctrl |= IXGBE_CTRL_GIO_DIS;
-       IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl);
+       /* Disable the receive unit by stopping each queue */
+       number_of_queues = hw->mac.max_rx_queues;
+       for (i = 0; i < number_of_queues; i++) {
+               reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i));
+               if (reg_val & IXGBE_RXDCTL_ENABLE) {
+                       reg_val &= ~IXGBE_RXDCTL_ENABLE;
+                       IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val);
+               }
+       }
+
+       reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL);
+       reg_val |= IXGBE_CTRL_GIO_DIS;
+       IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val);
 
        for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) {
                if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) {
@@ -1188,11 +1532,11 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw)
 
 
 /**
- *  ixgbe_acquire_swfw_sync - Aquire SWFW semaphore
+ *  ixgbe_acquire_swfw_sync - Acquire SWFW semaphore
  *  @hw: pointer to hardware structure
- *  @mask: Mask to specify wich semaphore to acquire
+ *  @mask: Mask to specify which semaphore to acquire
  *
- *  Aquires the SWFW semaphore throught the GSSR register for the specified
+ *  Acquires the SWFW semaphore thought the GSSR register for the specified
  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
  **/
 s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
@@ -1234,9 +1578,9 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask)
 /**
  *  ixgbe_release_swfw_sync - Release SWFW semaphore
  *  @hw: pointer to hardware structure
- *  @mask: Mask to specify wich semaphore to release
+ *  @mask: Mask to specify which semaphore to release
  *
- *  Releases the SWFW semaphore throught the GSSR register for the specified
+ *  Releases the SWFW semaphore thought the GSSR register for the specified
  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
  **/
 void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
@@ -1253,45 +1597,3 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask)
        ixgbe_release_eeprom_semaphore(hw);
 }
 
-/**
- *  ixgbe_read_analog_reg8 - Reads 8 bit Atlas analog register
- *  @hw: pointer to hardware structure
- *  @reg: analog register to read
- *  @val: read value
- *
- *  Performs write operation to analog register specified.
- **/
-s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val)
-{
-       u32  atlas_ctl;
-
-       IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL,
-                       IXGBE_ATLASCTL_WRITE_CMD | (reg << 8));
-       IXGBE_WRITE_FLUSH(hw);
-       udelay(10);
-       atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL);
-       *val = (u8)atlas_ctl;
-
-       return 0;
-}
-
-/**
- *  ixgbe_write_analog_reg8 - Writes 8 bit Atlas analog register
- *  @hw: pointer to hardware structure
- *  @reg: atlas register to write
- *  @val: value to write
- *
- *  Performs write operation to Atlas analog register specified.
- **/
-s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val)
-{
-       u32  atlas_ctl;
-
-       atlas_ctl = (reg << 8) | val;
-       IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl);
-       IXGBE_WRITE_FLUSH(hw);
-       udelay(10);
-
-       return 0;
-}
-
index c75ecba9ccda46c2fa74fdc8576346749749bb4e..192f8d0129111724b25fb52a82cc4a02a02bd4f1 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 
 #include "ixgbe_type.h"
 
-s32 ixgbe_init_hw(struct ixgbe_hw *hw);
-s32 ixgbe_start_hw(struct ixgbe_hw *hw);
-s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr);
-s32 ixgbe_stop_adapter(struct ixgbe_hw *hw);
-s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num);
-
-s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index);
-s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index);
-
-s32 ixgbe_init_eeprom(struct ixgbe_hw *hw);
-s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data);
-s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val);
-
-s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind,
-                 u32 enable_addr);
-s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list,
-                             u32 mc_addr_count, ixgbe_mc_addr_itr next);
-s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *uc_addr_list,
-                             u32 mc_addr_count, ixgbe_mc_addr_itr next);
-s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on);
-s32 ixgbe_validate_mac_addr(u8 *mac_addr);
-
-s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
+s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num);
+s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr);
+s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw);
+s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw);
+
+s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index);
+
+s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+                                       u16 *data);
+s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
+                                           u16 *checksum_val);
+s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
+
+s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
+                          u32 enable_addr);
+s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index);
+s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw);
+s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
+                                      u32 mc_addr_count,
+                                      ixgbe_mc_addr_itr func);
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
+                                      u32 addr_count, ixgbe_mc_addr_itr func);
+s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
+s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
 
+s32 ixgbe_validate_mac_addr(u8 *mac_addr);
 s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask);
 void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask);
 s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw);
 
-s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val);
-s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val);
+s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val);
+s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val);
 
 #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
 
index 61c000e230941602f3b693ee831db2f8657a35a6..81a9c4b8672683a8033ef5e73e3a4096e5e7a724 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
@@ -48,7 +47,7 @@ struct ixgbe_stats {
 };
 
 #define IXGBE_STAT(m) sizeof(((struct ixgbe_adapter *)0)->m), \
-                     offsetof(struct ixgbe_adapter, m)
+                             offsetof(struct ixgbe_adapter, m)
 static struct ixgbe_stats ixgbe_gstrings_stats[] = {
        {"rx_packets", IXGBE_STAT(net_stats.rx_packets)},
        {"tx_packets", IXGBE_STAT(net_stats.tx_packets)},
@@ -95,14 +94,15 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
 };
 
 #define IXGBE_QUEUE_STATS_LEN \
-               ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \
-                ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \
-                (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
-#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
+                ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \
+                 ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \
+                 (sizeof(struct ixgbe_queue_stats) / sizeof(u64)))
+#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
+#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats)
 #define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN)
 
 static int ixgbe_get_settings(struct net_device *netdev,
-                             struct ethtool_cmd *ecmd)
+                              struct ethtool_cmd *ecmd)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
@@ -114,7 +114,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
        ecmd->transceiver = XCVR_EXTERNAL;
        if (hw->phy.media_type == ixgbe_media_type_copper) {
                ecmd->supported |= (SUPPORTED_1000baseT_Full |
-                                   SUPPORTED_TP | SUPPORTED_Autoneg);
+                                   SUPPORTED_TP | SUPPORTED_Autoneg);
 
                ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg);
                if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
@@ -126,14 +126,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
        } else {
                ecmd->supported |= SUPPORTED_FIBRE;
                ecmd->advertising = (ADVERTISED_10000baseT_Full |
-                                    ADVERTISED_FIBRE);
+                                    ADVERTISED_FIBRE);
                ecmd->port = PORT_FIBRE;
+               ecmd->autoneg = AUTONEG_DISABLE;
        }
 
-       adapter->hw.mac.ops.check_link(hw, &(link_speed), &link_up);
+       hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
        if (link_up) {
                ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
-                               SPEED_10000 : SPEED_1000;
+                              SPEED_10000 : SPEED_1000;
                ecmd->duplex = DUPLEX_FULL;
        } else {
                ecmd->speed = -1;
@@ -144,7 +145,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
 }
 
 static int ixgbe_set_settings(struct net_device *netdev,
-                             struct ethtool_cmd *ecmd)
+                              struct ethtool_cmd *ecmd)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
@@ -164,7 +165,7 @@ static int ixgbe_set_settings(struct net_device *netdev,
 }
 
 static void ixgbe_get_pauseparam(struct net_device *netdev,
-                                struct ethtool_pauseparam *pause)
+                                 struct ethtool_pauseparam *pause)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
@@ -182,7 +183,7 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
 }
 
 static int ixgbe_set_pauseparam(struct net_device *netdev,
-                               struct ethtool_pauseparam *pause)
+                                struct ethtool_pauseparam *pause)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
@@ -241,7 +242,7 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
        if (data)
                netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
        else
-               netdev->features &= ~NETIF_F_IP_CSUM;
+               netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
 
        return 0;
 }
@@ -281,7 +282,7 @@ static int ixgbe_get_regs_len(struct net_device *netdev)
 #define IXGBE_GET_STAT(_A_, _R_) _A_->stats._R_
 
 static void ixgbe_get_regs(struct net_device *netdev,
-                          struct ethtool_regs *regs, void *p)
+                           struct ethtool_regs *regs, void *p)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
@@ -315,7 +316,9 @@ static void ixgbe_get_regs(struct net_device *netdev,
        regs_buff[17] = IXGBE_READ_REG(hw, IXGBE_GRC);
 
        /* Interrupt */
-       regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICR);
+       /* don't read EICR because it can clear interrupt causes, instead
+        * read EICS which is a shadow but doesn't clear EICR */
+       regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICS);
        regs_buff[19] = IXGBE_READ_REG(hw, IXGBE_EICS);
        regs_buff[20] = IXGBE_READ_REG(hw, IXGBE_EIMS);
        regs_buff[21] = IXGBE_READ_REG(hw, IXGBE_EIMC);
@@ -325,7 +328,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
        regs_buff[25] = IXGBE_READ_REG(hw, IXGBE_IVAR(0));
        regs_buff[26] = IXGBE_READ_REG(hw, IXGBE_MSIXT);
        regs_buff[27] = IXGBE_READ_REG(hw, IXGBE_MSIXPBA);
-       regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL);
+       regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL(0));
        regs_buff[29] = IXGBE_READ_REG(hw, IXGBE_GPIE);
 
        /* Flow Control */
@@ -371,7 +374,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
                regs_buff[482 + i] = IXGBE_READ_REG(hw, IXGBE_RAL(i));
        for (i = 0; i < 16; i++)
                regs_buff[498 + i] = IXGBE_READ_REG(hw, IXGBE_RAH(i));
-       regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE);
+       regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE(0));
        regs_buff[515] = IXGBE_READ_REG(hw, IXGBE_FCTRL);
        regs_buff[516] = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
        regs_buff[517] = IXGBE_READ_REG(hw, IXGBE_MCSTCTRL);
@@ -419,7 +422,6 @@ static void ixgbe_get_regs(struct net_device *netdev,
        regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
        regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT);
 
-       /* DCE */
        regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
        regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
        regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
@@ -539,21 +541,17 @@ static void ixgbe_get_regs(struct net_device *netdev,
        /* Diagnostic */
        regs_buff[1071] = IXGBE_READ_REG(hw, IXGBE_RDSTATCTL);
        for (i = 0; i < 8; i++)
-               regs_buff[1072] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i));
+               regs_buff[1072 + i] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i));
        regs_buff[1080] = IXGBE_READ_REG(hw, IXGBE_RDHMPN);
-       regs_buff[1081] = IXGBE_READ_REG(hw, IXGBE_RIC_DW0);
-       regs_buff[1082] = IXGBE_READ_REG(hw, IXGBE_RIC_DW1);
-       regs_buff[1083] = IXGBE_READ_REG(hw, IXGBE_RIC_DW2);
-       regs_buff[1084] = IXGBE_READ_REG(hw, IXGBE_RIC_DW3);
+       for (i = 0; i < 4; i++)
+               regs_buff[1081 + i] = IXGBE_READ_REG(hw, IXGBE_RIC_DW(i));
        regs_buff[1085] = IXGBE_READ_REG(hw, IXGBE_RDPROBE);
        regs_buff[1086] = IXGBE_READ_REG(hw, IXGBE_TDSTATCTL);
        for (i = 0; i < 8; i++)
-               regs_buff[1087] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i));
+               regs_buff[1087 + i] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i));
        regs_buff[1095] = IXGBE_READ_REG(hw, IXGBE_TDHMPN);
-       regs_buff[1096] = IXGBE_READ_REG(hw, IXGBE_TIC_DW0);
-       regs_buff[1097] = IXGBE_READ_REG(hw, IXGBE_TIC_DW1);
-       regs_buff[1098] = IXGBE_READ_REG(hw, IXGBE_TIC_DW2);
-       regs_buff[1099] = IXGBE_READ_REG(hw, IXGBE_TIC_DW3);
+       for (i = 0; i < 4; i++)
+               regs_buff[1096 + i] = IXGBE_READ_REG(hw, IXGBE_TIC_DW(i));
        regs_buff[1100] = IXGBE_READ_REG(hw, IXGBE_TDPROBE);
        regs_buff[1101] = IXGBE_READ_REG(hw, IXGBE_TXBUFCTRL);
        regs_buff[1102] = IXGBE_READ_REG(hw, IXGBE_TXBUFDATA0);
@@ -566,7 +564,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
        regs_buff[1109] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA2);
        regs_buff[1110] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA3);
        for (i = 0; i < 8; i++)
-               regs_buff[1111] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i));
+               regs_buff[1111 + i] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i));
        regs_buff[1119] = IXGBE_READ_REG(hw, IXGBE_RFVAL);
        regs_buff[1120] = IXGBE_READ_REG(hw, IXGBE_MDFTC1);
        regs_buff[1121] = IXGBE_READ_REG(hw, IXGBE_MDFTC2);
@@ -585,7 +583,7 @@ static int ixgbe_get_eeprom_len(struct net_device *netdev)
 }
 
 static int ixgbe_get_eeprom(struct net_device *netdev,
-                           struct ethtool_eeprom *eeprom, u8 *bytes)
+                            struct ethtool_eeprom *eeprom, u8 *bytes)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
@@ -608,8 +606,8 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
                return -ENOMEM;
 
        for (i = 0; i < eeprom_len; i++) {
-               if ((ret_val = ixgbe_read_eeprom(hw, first_word + i,
-                                                &eeprom_buff[i])))
+               if ((ret_val = hw->eeprom.ops.read(hw, first_word + i,
+                   &eeprom_buff[i])))
                        break;
        }
 
@@ -624,7 +622,7 @@ static int ixgbe_get_eeprom(struct net_device *netdev,
 }
 
 static void ixgbe_get_drvinfo(struct net_device *netdev,
-                             struct ethtool_drvinfo *drvinfo)
+                              struct ethtool_drvinfo *drvinfo)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
@@ -637,7 +635,7 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
 }
 
 static void ixgbe_get_ringparam(struct net_device *netdev,
-                               struct ethtool_ringparam *ring)
+                                struct ethtool_ringparam *ring)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_ring *tx_ring = adapter->tx_ring;
@@ -654,15 +652,12 @@ static void ixgbe_get_ringparam(struct net_device *netdev,
 }
 
 static int ixgbe_set_ringparam(struct net_device *netdev,
-                              struct ethtool_ringparam *ring)
+                               struct ethtool_ringparam *ring)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       struct ixgbe_tx_buffer *old_buf;
-       struct ixgbe_rx_buffer *old_rx_buf;
-       void *old_desc;
+       struct ixgbe_ring *temp_ring;
        int i, err;
-       u32 new_rx_count, new_tx_count, old_size;
-       dma_addr_t old_dma;
+       u32 new_rx_count, new_tx_count;
 
        if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
                return -EINVAL;
@@ -681,6 +676,15 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
                return 0;
        }
 
+       if (adapter->num_tx_queues > adapter->num_rx_queues)
+               temp_ring = vmalloc(adapter->num_tx_queues *
+                                   sizeof(struct ixgbe_ring));
+       else
+               temp_ring = vmalloc(adapter->num_rx_queues *
+                                   sizeof(struct ixgbe_ring));
+       if (!temp_ring)
+               return -ENOMEM;
+
        while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
                msleep(1);
 
@@ -693,66 +697,61 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
         * to the tx and rx ring structs.
         */
        if (new_tx_count != adapter->tx_ring->count) {
+               memcpy(temp_ring, adapter->tx_ring,
+                      adapter->num_tx_queues * sizeof(struct ixgbe_ring));
+
                for (i = 0; i < adapter->num_tx_queues; i++) {
-                       /* Save existing descriptor ring */
-                       old_buf = adapter->tx_ring[i].tx_buffer_info;
-                       old_desc = adapter->tx_ring[i].desc;
-                       old_size = adapter->tx_ring[i].size;
-                       old_dma = adapter->tx_ring[i].dma;
-                       /* Try to allocate a new one */
-                       adapter->tx_ring[i].tx_buffer_info = NULL;
-                       adapter->tx_ring[i].desc = NULL;
-                       adapter->tx_ring[i].count = new_tx_count;
-                       err = ixgbe_setup_tx_resources(adapter,
-                                                      &adapter->tx_ring[i]);
+                       temp_ring[i].count = new_tx_count;
+                       err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]);
                        if (err) {
-                               /* Restore the old one so at least
-                                  the adapter still works, even if
-                                  we failed the request */
-                               adapter->tx_ring[i].tx_buffer_info = old_buf;
-                               adapter->tx_ring[i].desc = old_desc;
-                               adapter->tx_ring[i].size = old_size;
-                               adapter->tx_ring[i].dma = old_dma;
+                               while (i) {
+                                       i--;
+                                       ixgbe_free_tx_resources(adapter,
+                                                               &temp_ring[i]);
+                               }
                                goto err_setup;
                        }
-                       /* Free the old buffer manually */
-                       vfree(old_buf);
-                       pci_free_consistent(adapter->pdev, old_size,
-                                           old_desc, old_dma);
                }
+
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]);
+
+               memcpy(adapter->tx_ring, temp_ring,
+                      adapter->num_tx_queues * sizeof(struct ixgbe_ring));
+
+               adapter->tx_ring_count = new_tx_count;
        }
 
        if (new_rx_count != adapter->rx_ring->count) {
-               for (i = 0; i < adapter->num_rx_queues; i++) {
+               memcpy(temp_ring, adapter->rx_ring,
+                      adapter->num_rx_queues * sizeof(struct ixgbe_ring));
 
-                       old_rx_buf = adapter->rx_ring[i].rx_buffer_info;
-                       old_desc = adapter->rx_ring[i].desc;
-                       old_size = adapter->rx_ring[i].size;
-                       old_dma = adapter->rx_ring[i].dma;
-
-                       adapter->rx_ring[i].rx_buffer_info = NULL;
-                       adapter->rx_ring[i].desc = NULL;
-                       adapter->rx_ring[i].dma = 0;
-                       adapter->rx_ring[i].count = new_rx_count;
-                       err = ixgbe_setup_rx_resources(adapter,
-                                                      &adapter->rx_ring[i]);
+               for (i = 0; i < adapter->num_rx_queues; i++) {
+                       temp_ring[i].count = new_rx_count;
+                       err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]);
                        if (err) {
-                               adapter->rx_ring[i].rx_buffer_info = old_rx_buf;
-                               adapter->rx_ring[i].desc = old_desc;
-                               adapter->rx_ring[i].size = old_size;
-                               adapter->rx_ring[i].dma = old_dma;
+                               while (i) {
+                                       i--;
+                                       ixgbe_free_rx_resources(adapter,
+                                                               &temp_ring[i]);
+                               }
                                goto err_setup;
                        }
-
-                       vfree(old_rx_buf);
-                       pci_free_consistent(adapter->pdev, old_size, old_desc,
-                                           old_dma);
                }
+
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
+
+               memcpy(adapter->rx_ring, temp_ring,
+                      adapter->num_rx_queues * sizeof(struct ixgbe_ring));
+
+               adapter->rx_ring_count = new_rx_count;
        }
 
+       /* success! */
        err = 0;
 err_setup:
-       if (netif_running(adapter->netdev))
+       if (netif_running(netdev))
                ixgbe_up(adapter);
 
        clear_bit(__IXGBE_RESETTING, &adapter->state);
@@ -770,7 +769,7 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset)
 }
 
 static void ixgbe_get_ethtool_stats(struct net_device *netdev,
-                                   struct ethtool_stats *stats, u64 *data)
+                                    struct ethtool_stats *stats, u64 *data)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        u64 *queue_stat;
@@ -778,12 +777,20 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
        int j, k;
        int i;
        u64 aggregated = 0, flushed = 0, no_desc = 0;
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated;
+               flushed += adapter->rx_ring[i].lro_mgr.stats.flushed;
+               no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc;
+       }
+       adapter->lro_aggregated = aggregated;
+       adapter->lro_flushed = flushed;
+       adapter->lro_no_desc = no_desc;
 
        ixgbe_update_stats(adapter);
        for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
                char *p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset;
                data[i] = (ixgbe_gstrings_stats[i].sizeof_stat ==
-                          sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
+                          sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
        }
        for (j = 0; j < adapter->num_tx_queues; j++) {
                queue_stat = (u64 *)&adapter->tx_ring[j].stats;
@@ -792,24 +799,18 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev,
                i += k;
        }
        for (j = 0; j < adapter->num_rx_queues; j++) {
-               aggregated += adapter->rx_ring[j].lro_mgr.stats.aggregated;
-               flushed += adapter->rx_ring[j].lro_mgr.stats.flushed;
-               no_desc += adapter->rx_ring[j].lro_mgr.stats.no_desc;
                queue_stat = (u64 *)&adapter->rx_ring[j].stats;
                for (k = 0; k < stat_count; k++)
                        data[i + k] = queue_stat[k];
                i += k;
        }
-       adapter->lro_aggregated = aggregated;
-       adapter->lro_flushed = flushed;
-       adapter->lro_no_desc = no_desc;
 }
 
 static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
-                             u8 *data)
+                              u8 *data)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       u8 *p = data;
+       char *p = (char *)data;
        int i;
 
        switch (stringset) {
@@ -831,14 +832,14 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
                        sprintf(p, "rx_queue_%u_bytes", i);
                        p += ETH_GSTRING_LEN;
                }
-/*             BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
+               /* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */
                break;
        }
 }
 
 
 static void ixgbe_get_wol(struct net_device *netdev,
-                         struct ethtool_wolinfo *wol)
+                          struct ethtool_wolinfo *wol)
 {
        wol->supported = 0;
        wol->wolopts = 0;
@@ -859,16 +860,17 @@ static int ixgbe_nway_reset(struct net_device *netdev)
 static int ixgbe_phys_id(struct net_device *netdev, u32 data)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       u32 led_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_LEDCTL);
+       struct ixgbe_hw *hw = &adapter->hw;
+       u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
        u32 i;
 
        if (!data || data > 300)
                data = 300;
 
        for (i = 0; i < (data * 1000); i += 400) {
-               ixgbe_led_on(&adapter->hw, IXGBE_LED_ON);
+               hw->mac.ops.led_on(hw, IXGBE_LED_ON);
                msleep_interruptible(200);
-               ixgbe_led_off(&adapter->hw, IXGBE_LED_ON);
+               hw->mac.ops.led_off(hw, IXGBE_LED_ON);
                msleep_interruptible(200);
        }
 
@@ -879,67 +881,75 @@ static int ixgbe_phys_id(struct net_device *netdev, u32 data)
 }
 
 static int ixgbe_get_coalesce(struct net_device *netdev,
-                             struct ethtool_coalesce *ec)
+                              struct ethtool_coalesce *ec)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
-       if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
-               ec->rx_coalesce_usecs = adapter->rx_eitr;
-       else
-               ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr;
-
-       if (adapter->tx_eitr < IXGBE_MIN_ITR_USECS)
-               ec->tx_coalesce_usecs = adapter->tx_eitr;
-       else
-               ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr;
-
        ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit;
+
+       /* only valid if in constant ITR mode */
+       switch (adapter->itr_setting) {
+       case 0:
+               /* throttling disabled */
+               ec->rx_coalesce_usecs = 0;
+               break;
+       case 1:
+               /* dynamic ITR mode */
+               ec->rx_coalesce_usecs = 1;
+               break;
+       default:
+               /* fixed interrupt rate mode */
+               ec->rx_coalesce_usecs = 1000000/adapter->eitr_param;
+               break;
+       }
        return 0;
 }
 
 static int ixgbe_set_coalesce(struct net_device *netdev,
-                             struct ethtool_coalesce *ec)
+                              struct ethtool_coalesce *ec)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
-
-       if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
-           ((ec->rx_coalesce_usecs != 0) &&
-            (ec->rx_coalesce_usecs != 1) &&
-            (ec->rx_coalesce_usecs != 3) &&
-            (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
-               return -EINVAL;
-       if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) ||
-           ((ec->tx_coalesce_usecs != 0) &&
-            (ec->tx_coalesce_usecs != 1) &&
-            (ec->tx_coalesce_usecs != 3) &&
-            (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)))
-               return -EINVAL;
-
-       /* convert to rate of irq's per second */
-       if (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
-               adapter->rx_eitr = ec->rx_coalesce_usecs;
-       else
-               adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs);
-
-       if (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS)
-               adapter->tx_eitr = ec->rx_coalesce_usecs;
-       else
-               adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs);
+       struct ixgbe_hw *hw = &adapter->hw;
+       int i;
 
        if (ec->tx_max_coalesced_frames_irq)
-               adapter->tx_ring[0].work_limit =
-                                       ec->tx_max_coalesced_frames_irq;
+               adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq;
+
+       if (ec->rx_coalesce_usecs > 1) {
+               /* store the value in ints/second */
+               adapter->eitr_param = 1000000/ec->rx_coalesce_usecs;
+
+               /* static value of interrupt rate */
+               adapter->itr_setting = adapter->eitr_param;
+               /* clear the lower bit */
+               adapter->itr_setting &= ~1;
+       } else if (ec->rx_coalesce_usecs == 1) {
+               /* 1 means dynamic mode */
+               adapter->eitr_param = 20000;
+               adapter->itr_setting = 1;
+       } else {
+               /* any other value means disable eitr, which is best
+                * served by setting the interrupt rate very high */
+               adapter->eitr_param = 3000000;
+               adapter->itr_setting = 0;
+       }
 
-       if (netif_running(netdev)) {
-               ixgbe_down(adapter);
-               ixgbe_up(adapter);
+       for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+               struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+               if (q_vector->txr_count && !q_vector->rxr_count)
+                       q_vector->eitr = (adapter->eitr_param >> 1);
+               else
+                       /* rx only or mixed */
+                       q_vector->eitr = adapter->eitr_param;
+               IXGBE_WRITE_REG(hw, IXGBE_EITR(i),
+                               EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
        }
 
        return 0;
 }
 
 
-static struct ethtool_ops ixgbe_ethtool_ops = {
+static const struct ethtool_ops ixgbe_ethtool_ops = {
        .get_settings           = ixgbe_get_settings,
        .set_settings           = ixgbe_set_settings,
        .get_drvinfo            = ixgbe_get_drvinfo,
@@ -966,7 +976,7 @@ static struct ethtool_ops ixgbe_ethtool_ops = {
        .set_tso                = ixgbe_set_tso,
        .get_strings            = ixgbe_get_strings,
        .phys_id                = ixgbe_phys_id,
-       .get_sset_count         = ixgbe_get_sset_count,
+       .get_sset_count         = ixgbe_get_sset_count,
        .get_ethtool_stats      = ixgbe_get_ethtool_stats,
        .get_coalesce           = ixgbe_get_coalesce,
        .set_coalesce           = ixgbe_set_coalesce,
index 362541aa946efcb569d5396c04b495b159fd6d7e..ca17af4349d03ee6283f2f3340c1107d7ad1ed8b 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 
 char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
-       "Intel(R) 10 Gigabit PCI Express Network Driver";
+                              "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "1.3.18-k4"
+#define DRV_VERSION "1.3.30-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
-static const char ixgbe_copyright[] =
-        "Copyright (c) 1999-2007 Intel Corporation.";
+static char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation.";
 
 static const struct ixgbe_info *ixgbe_info_tbl[] = {
-       [board_82598]                   = &ixgbe_82598_info,
+       [board_82598] = &ixgbe_82598_info,
 };
 
 /* ixgbe_pci_tbl - PCI Device ID Table
@@ -74,15 +72,17 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
         board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
         board_82598 },
+       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_XF_LR),
+        board_82598 },
 
        /* required last entry */
        {0, }
 };
 MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
 static int ixgbe_notify_dca(struct notifier_block *, unsigned long event,
-                           void *p);
+                            void *p);
 static struct notifier_block dca_notifier = {
        .notifier_call = ixgbe_notify_dca,
        .next          = NULL,
@@ -104,7 +104,7 @@ static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
        /* Let firmware take over control of h/w */
        ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
-                       ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
+                       ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
 }
 
 static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
@@ -114,24 +114,11 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
        /* Let firmware know the driver has taken over */
        ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
-                       ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
-}
-
-#ifdef DEBUG
-/**
- * ixgbe_get_hw_dev_name - return device name string
- * used by hardware layer to print debugging information
- **/
-char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw)
-{
-       struct ixgbe_adapter *adapter = hw->back;
-       struct net_device *netdev = adapter->netdev;
-       return netdev->name;
+                       ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
 }
-#endif
 
 static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
-                          u8 msix_vector)
+                           u8 msix_vector)
 {
        u32 ivar, index;
 
@@ -144,12 +131,12 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry,
 }
 
 static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
-                                            struct ixgbe_tx_buffer
-                                            *tx_buffer_info)
+                                             struct ixgbe_tx_buffer
+                                             *tx_buffer_info)
 {
        if (tx_buffer_info->dma) {
                pci_unmap_page(adapter->pdev, tx_buffer_info->dma,
-                              tx_buffer_info->length, PCI_DMA_TODEVICE);
+                              tx_buffer_info->length, PCI_DMA_TODEVICE);
                tx_buffer_info->dma = 0;
        }
        if (tx_buffer_info->skb) {
@@ -160,8 +147,8 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
 }
 
 static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
-                                      struct ixgbe_ring *tx_ring,
-                                      unsigned int eop)
+                                       struct ixgbe_ring *tx_ring,
+                                       unsigned int eop)
 {
        struct ixgbe_hw *hw = &adapter->hw;
        u32 head, tail;
@@ -196,14 +183,14 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
        return false;
 }
 
-#define IXGBE_MAX_TXD_PWR      14
-#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR)
+#define IXGBE_MAX_TXD_PWR       14
+#define IXGBE_MAX_DATA_PER_TXD  (1 << IXGBE_MAX_TXD_PWR)
 
 /* Tx Descriptors needed, worst case */
 #define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \
                         (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
 #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
-       MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1)   /* for context */
+       MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
 
 #define GET_TX_HEAD_FROM_RING(ring) (\
        *(volatile u32 *) \
@@ -309,9 +296,9 @@ done_cleaning:
        return (total_packets ? true : false);
 }
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
 static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
-                               struct ixgbe_ring *rx_ring)
+                                struct ixgbe_ring *rx_ring)
 {
        u32 rxctrl;
        int cpu = get_cpu();
@@ -330,7 +317,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter,
 }
 
 static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter,
-                               struct ixgbe_ring *tx_ring)
+                                struct ixgbe_ring *tx_ring)
 {
        u32 txctrl;
        int cpu = get_cpu();
@@ -406,8 +393,8 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
  * @rx_desc: rx descriptor
  **/
 static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
-                             struct sk_buff *skb, u8 status,
-                             struct ixgbe_ring *ring,
+                              struct sk_buff *skb, u8 status,
+                              struct ixgbe_ring *ring,
                               union ixgbe_adv_rx_desc *rx_desc)
 {
        bool is_vlan = (status & IXGBE_RXD_STAT_VP);
@@ -480,7 +467,6 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
                                    struct ixgbe_ring *rx_ring,
                                    int cleaned_count)
 {
-       struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        union ixgbe_adv_rx_desc *rx_desc;
        struct ixgbe_rx_buffer *bi;
@@ -493,20 +479,29 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter,
        while (cleaned_count--) {
                rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
 
-               if (!bi->page &&
+               if (!bi->page_dma &&
                    (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) {
-                       bi->page = alloc_page(GFP_ATOMIC);
                        if (!bi->page) {
-                               adapter->alloc_rx_page_failed++;
-                               goto no_buffers;
+                               bi->page = alloc_page(GFP_ATOMIC);
+                               if (!bi->page) {
+                                       adapter->alloc_rx_page_failed++;
+                                       goto no_buffers;
+                               }
+                               bi->page_offset = 0;
+                       } else {
+                               /* use a half page if we're re-using */
+                               bi->page_offset ^= (PAGE_SIZE / 2);
                        }
-                       bi->page_dma = pci_map_page(pdev, bi->page, 0,
-                                                   PAGE_SIZE,
-                                                   PCI_DMA_FROMDEVICE);
+
+                       bi->page_dma = pci_map_page(pdev, bi->page,
+                                                   bi->page_offset,
+                                                   (PAGE_SIZE / 2),
+                                                   PCI_DMA_FROMDEVICE);
                }
 
                if (!bi->skb) {
-                       struct sk_buff *skb = netdev_alloc_skb(netdev, bufsz);
+                       struct sk_buff *skb = netdev_alloc_skb(adapter->netdev,
+                                                              bufsz);
 
                        if (!skb) {
                                adapter->alloc_rx_buff_failed++;
@@ -567,10 +562,9 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
 }
 
 static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
-                              struct ixgbe_ring *rx_ring,
-                              int *work_done, int work_to_do)
+                               struct ixgbe_ring *rx_ring,
+                               int *work_done, int work_to_do)
 {
-       struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
        struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
@@ -596,7 +590,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
                if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
                        hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc));
                        len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
-                              IXGBE_RXDADV_HDRBUFLEN_SHIFT;
+                              IXGBE_RXDADV_HDRBUFLEN_SHIFT;
                        if (hdr_info & IXGBE_RXDADV_SPH)
                                adapter->rx_hdr_split++;
                        if (len > IXGBE_RX_HDR_SIZE)
@@ -613,18 +607,25 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
 
                if (len && !skb_shinfo(skb)->nr_frags) {
                        pci_unmap_single(pdev, rx_buffer_info->dma,
-                                        rx_ring->rx_buf_len + NET_IP_ALIGN,
-                                        PCI_DMA_FROMDEVICE);
+                                        rx_ring->rx_buf_len + NET_IP_ALIGN,
+                                        PCI_DMA_FROMDEVICE);
                        skb_put(skb, len);
                }
 
                if (upper_len) {
                        pci_unmap_page(pdev, rx_buffer_info->page_dma,
-                                      PAGE_SIZE, PCI_DMA_FROMDEVICE);
+                                      PAGE_SIZE / 2, PCI_DMA_FROMDEVICE);
                        rx_buffer_info->page_dma = 0;
                        skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags,
-                                          rx_buffer_info->page, 0, upper_len);
-                       rx_buffer_info->page = NULL;
+                                          rx_buffer_info->page,
+                                          rx_buffer_info->page_offset,
+                                          upper_len);
+
+                       if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) ||
+                           (page_count(rx_buffer_info->page) != 1))
+                               rx_buffer_info->page = NULL;
+                       else
+                               get_page(rx_buffer_info->page);
 
                        skb->len += upper_len;
                        skb->data_len += upper_len;
@@ -647,6 +648,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
                        rx_buffer_info->skb = next_buffer->skb;
                        rx_buffer_info->dma = next_buffer->dma;
                        next_buffer->skb = skb;
+                       next_buffer->dma = 0;
                        adapter->non_eop_descs++;
                        goto next_desc;
                }
@@ -662,9 +664,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
                total_rx_bytes += skb->len;
                total_rx_packets++;
 
-               skb->protocol = eth_type_trans(skb, netdev);
+               skb->protocol = eth_type_trans(skb, adapter->netdev);
                ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc);
-               netdev->last_rx = jiffies;
+               adapter->netdev->last_rx = jiffies;
 
 next_desc:
                rx_desc->wb.upper.status_error = 0;
@@ -724,43 +726,43 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
                q_vector = &adapter->q_vector[v_idx];
                /* XXX for_each_bit(...) */
                r_idx = find_first_bit(q_vector->rxr_idx,
-                                     adapter->num_rx_queues);
+                                      adapter->num_rx_queues);
 
                for (i = 0; i < q_vector->rxr_count; i++) {
                        j = adapter->rx_ring[r_idx].reg_idx;
                        ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(j), v_idx);
                        r_idx = find_next_bit(q_vector->rxr_idx,
-                                             adapter->num_rx_queues,
-                                             r_idx + 1);
+                                             adapter->num_rx_queues,
+                                             r_idx + 1);
                }
                r_idx = find_first_bit(q_vector->txr_idx,
-                                      adapter->num_tx_queues);
+                                      adapter->num_tx_queues);
 
                for (i = 0; i < q_vector->txr_count; i++) {
                        j = adapter->tx_ring[r_idx].reg_idx;
                        ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(j), v_idx);
                        r_idx = find_next_bit(q_vector->txr_idx,
-                                             adapter->num_tx_queues,
-                                             r_idx + 1);
+                                             adapter->num_tx_queues,
+                                             r_idx + 1);
                }
 
-               /* if this is a tx only vector use half the irq (tx) rate */
+               /* if this is a tx only vector halve the interrupt rate */
                if (q_vector->txr_count && !q_vector->rxr_count)
-                       q_vector->eitr = adapter->tx_eitr;
+                       q_vector->eitr = (adapter->eitr_param >> 1);
                else
-                       /* rx only or mixed */
-                       q_vector->eitr = adapter->rx_eitr;
+                       /* rx only */
+                       q_vector->eitr = adapter->eitr_param;
 
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx),
-                               EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+                               EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
        }
 
        ixgbe_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx);
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950);
 
-       /* set up to autoclear timer, lsc, and the vectors */
+       /* set up to autoclear timer, and the vectors */
        mask = IXGBE_EIMS_ENABLE_MASK;
-       mask &= ~IXGBE_EIMS_OTHER;
+       mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC);
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask);
 }
 
@@ -790,8 +792,8 @@ enum latency_range {
  *      parameter (see ixgbe_param.c)
  **/
 static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter,
-                          u32 eitr, u8 itr_setting,
-                          int packets, int bytes)
+                           u32 eitr, u8 itr_setting,
+                           int packets, int bytes)
 {
        unsigned int retval = itr_setting;
        u32 timepassed_us;
@@ -838,40 +840,40 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
        u32 new_itr;
        u8 current_itr, ret_itr;
        int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
-                             sizeof(struct ixgbe_q_vector);
+                              sizeof(struct ixgbe_q_vector);
        struct ixgbe_ring *rx_ring, *tx_ring;
 
        r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
        for (i = 0; i < q_vector->txr_count; i++) {
                tx_ring = &(adapter->tx_ring[r_idx]);
                ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
-                                          q_vector->tx_eitr,
-                                          tx_ring->total_packets,
-                                          tx_ring->total_bytes);
+                                          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_eitr = ((q_vector->tx_eitr > ret_itr) ?
-                                   q_vector->tx_eitr - 1 : ret_itr);
+               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);
+                                     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++) {
                rx_ring = &(adapter->rx_ring[r_idx]);
                ret_itr = ixgbe_update_itr(adapter, q_vector->eitr,
-                                          q_vector->rx_eitr,
-                                          rx_ring->total_packets,
-                                          rx_ring->total_bytes);
+                                          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_eitr = ((q_vector->rx_eitr > ret_itr) ?
-                                   q_vector->rx_eitr - 1 : ret_itr);
+               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);
+                                     r_idx + 1);
        }
 
-       current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr);
+       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 */
@@ -895,13 +897,27 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
                itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
                /* must write high and low 16 bits to reset counter */
                DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx,
-                       itr_reg);
+                       itr_reg);
                IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16);
        }
 
        return;
 }
 
+
+static void ixgbe_check_lsc(struct ixgbe_adapter *adapter)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+
+       adapter->lsc_int++;
+       adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+       adapter->link_check_timeout = jiffies;
+       if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+               IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
+               schedule_work(&adapter->watchdog_task);
+       }
+}
+
 static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
 {
        struct net_device *netdev = data;
@@ -909,11 +925,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
        struct ixgbe_hw *hw = &adapter->hw;
        u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
 
-       if (eicr & IXGBE_EICR_LSC) {
-               adapter->lsc_int++;
-               if (!test_bit(__IXGBE_DOWN, &adapter->state))
-                       mod_timer(&adapter->watchdog_timer, jiffies);
-       }
+       if (eicr & IXGBE_EICR_LSC)
+               ixgbe_check_lsc(adapter);
 
        if (!test_bit(__IXGBE_DOWN, &adapter->state))
                IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
@@ -934,7 +947,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
        r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
        for (i = 0; i < q_vector->txr_count; i++) {
                tx_ring = &(adapter->tx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
                if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
                        ixgbe_update_tx_dca(adapter, tx_ring);
 #endif
@@ -942,7 +955,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
                tx_ring->total_packets = 0;
                ixgbe_clean_tx_irq(adapter, tx_ring);
                r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
-                                     r_idx + 1);
+                                     r_idx + 1);
        }
 
        return IRQ_HANDLED;
@@ -959,16 +972,24 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
        struct ixgbe_adapter  *adapter = q_vector->adapter;
        struct ixgbe_ring  *rx_ring;
        int r_idx;
+       int i;
 
        r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+       for (i = 0;  i < q_vector->rxr_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 + 1);
+       }
+
        if (!q_vector->rxr_count)
                return IRQ_HANDLED;
 
+       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
        rx_ring = &(adapter->rx_ring[r_idx]);
        /* disable interrupts on this vector only */
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
-       rx_ring->total_bytes = 0;
-       rx_ring->total_packets = 0;
        netif_rx_schedule(adapter->netdev, &q_vector->napi);
 
        return IRQ_HANDLED;
@@ -987,19 +1008,21 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
  * @napi: napi struct with our devices info in it
  * @budget: amount of work driver is allowed to do this pass, in packets
  *
+ * This function is optimized for cleaning one queue only on a single
+ * q_vector!!!
  **/
 static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
 {
        struct ixgbe_q_vector *q_vector =
-                              container_of(napi, struct ixgbe_q_vector, napi);
+                              container_of(napi, struct ixgbe_q_vector, napi);
        struct ixgbe_adapter *adapter = q_vector->adapter;
-       struct ixgbe_ring *rx_ring;
+       struct ixgbe_ring *rx_ring = NULL;
        int work_done = 0;
        long r_idx;
 
        r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
        rx_ring = &(adapter->rx_ring[r_idx]);
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
                ixgbe_update_rx_dca(adapter, rx_ring);
 #endif
@@ -1009,7 +1032,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
        /* If all Rx work done, exit the polling mode */
        if (work_done < budget) {
                netif_rx_complete(adapter->netdev, napi);
-               if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
+               if (adapter->itr_setting & 3)
                        ixgbe_set_itr_msix(q_vector);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
                        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
@@ -1018,8 +1041,57 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
        return work_done;
 }
 
+/**
+ * ixgbe_clean_rxonly_many - msix (aka one shot) rx clean routine
+ * @napi: napi struct with our devices info in it
+ * @budget: amount of work driver is allowed to do this pass, in packets
+ *
+ * This function will clean more than one rx queue associated with a
+ * q_vector.
+ **/
+static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
+{
+       struct ixgbe_q_vector *q_vector =
+                              container_of(napi, struct ixgbe_q_vector, napi);
+       struct ixgbe_adapter *adapter = q_vector->adapter;
+       struct ixgbe_ring *rx_ring = NULL;
+       int work_done = 0, i;
+       long r_idx;
+       u16 enable_mask = 0;
+
+       /* 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 = 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++) {
+               rx_ring = &(adapter->rx_ring[r_idx]);
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
+               if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+                       ixgbe_update_rx_dca(adapter, rx_ring);
+#endif
+               ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget);
+               enable_mask |= rx_ring->v_idx;
+               r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+                                     r_idx + 1);
+       }
+
+       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+       rx_ring = &(adapter->rx_ring[r_idx]);
+       /* If all Rx work done, exit the polling mode */
+       if (work_done < budget) {
+               netif_rx_complete(adapter->netdev, napi);
+               if (adapter->itr_setting & 3)
+                       ixgbe_set_itr_msix(q_vector);
+               if (!test_bit(__IXGBE_DOWN, &adapter->state))
+                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask);
+               return 0;
+       }
+
+       return work_done;
+}
 static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
-                                    int r_idx)
+                                     int r_idx)
 {
        a->q_vector[v_idx].adapter = a;
        set_bit(r_idx, a->q_vector[v_idx].rxr_idx);
@@ -1028,7 +1100,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
 }
 
 static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
-                                    int r_idx)
+                                     int r_idx)
 {
        a->q_vector[v_idx].adapter = a;
        set_bit(r_idx, a->q_vector[v_idx].txr_idx);
@@ -1048,7 +1120,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
  * mapping configurations in here.
  **/
 static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter,
-                                     int vectors)
+                                      int vectors)
 {
        int v_start = 0;
        int rxr_idx = 0, txr_idx = 0;
@@ -1125,28 +1197,28 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
                goto out;
 
 #define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \
-                        (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
-                        &ixgbe_msix_clean_many)
+                         (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
+                         &ixgbe_msix_clean_many)
        for (vector = 0; vector < q_vectors; vector++) {
                handler = SET_HANDLER(&adapter->q_vector[vector]);
                sprintf(adapter->name[vector], "%s:v%d-%s",
-                       netdev->name, vector,
-                       (handler == &ixgbe_msix_clean_rx) ? "Rx" :
-                        ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx"));
+                       netdev->name, vector,
+                       (handler == &ixgbe_msix_clean_rx) ? "Rx" :
+                        ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx"));
                err = request_irq(adapter->msix_entries[vector].vector,
-                                 handler, 0, adapter->name[vector],
-                                 &(adapter->q_vector[vector]));
+                                 handler, 0, adapter->name[vector],
+                                 &(adapter->q_vector[vector]));
                if (err) {
                        DPRINTK(PROBE, ERR,
-                               "request_irq failed for MSIX interrupt "
-                               "Error: %d\n", err);
+                               "request_irq failed for MSIX interrupt "
+                               "Error: %d\n", err);
                        goto free_queue_irqs;
                }
        }
 
        sprintf(adapter->name[vector], "%s:lsc", netdev->name);
        err = request_irq(adapter->msix_entries[vector].vector,
-                         &ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
+                         &ixgbe_msix_lsc, 0, adapter->name[vector], netdev);
        if (err) {
                DPRINTK(PROBE, ERR,
                        "request_irq for msix_lsc failed: %d\n", err);
@@ -1158,7 +1230,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
 free_queue_irqs:
        for (i = vector - 1; i >= 0; i--)
                free_irq(adapter->msix_entries[--vector].vector,
-                        &(adapter->q_vector[i]));
+                        &(adapter->q_vector[i]));
        adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
        pci_disable_msix(adapter->pdev);
        kfree(adapter->msix_entries);
@@ -1176,16 +1248,16 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
        struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
        struct ixgbe_ring *tx_ring = &adapter->tx_ring[0];
 
-       q_vector->tx_eitr = ixgbe_update_itr(adapter, new_itr,
-                                            q_vector->tx_eitr,
-                                            tx_ring->total_packets,
-                                            tx_ring->total_bytes);
-       q_vector->rx_eitr = ixgbe_update_itr(adapter, new_itr,
-                                            q_vector->rx_eitr,
-                                            rx_ring->total_packets,
-                                            rx_ring->total_bytes);
+       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_eitr, q_vector->tx_eitr);
+       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 */
@@ -1230,19 +1302,19 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
        struct ixgbe_hw *hw = &adapter->hw;
        u32 eicr;
 
-
        /* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read
         * therefore no explict interrupt disable is necessary */
        eicr = IXGBE_READ_REG(hw, IXGBE_EICR);
-       if (!eicr)
+       if (!eicr) {
+               /* shared interrupt alert!
+                * make sure interrupts are enabled because the read will
+                * have disabled interrupts due to EIAM */
+               ixgbe_irq_enable(adapter);
                return IRQ_NONE;        /* Not our interrupt */
-
-       if (eicr & IXGBE_EICR_LSC) {
-               adapter->lsc_int++;
-               if (!test_bit(__IXGBE_DOWN, &adapter->state))
-                       mod_timer(&adapter->watchdog_timer, jiffies);
        }
 
+       if (eicr & IXGBE_EICR_LSC)
+               ixgbe_check_lsc(adapter);
 
        if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) {
                adapter->tx_ring[0].total_packets = 0;
@@ -1285,10 +1357,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter)
                err = ixgbe_request_msix_irqs(adapter);
        } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
                err = request_irq(adapter->pdev->irq, &ixgbe_intr, 0,
-                                 netdev->name, netdev);
+                                 netdev->name, netdev);
        } else {
                err = request_irq(adapter->pdev->irq, &ixgbe_intr, IRQF_SHARED,
-                                 netdev->name, netdev);
+                                 netdev->name, netdev);
        }
 
        if (err)
@@ -1312,7 +1384,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
                i--;
                for (; i >= 0; i--) {
                        free_irq(adapter->msix_entries[i].vector,
-                                &(adapter->q_vector[i]));
+                                &(adapter->q_vector[i]));
                }
 
                ixgbe_reset_q_vectors(adapter);
@@ -1359,7 +1431,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
        struct ixgbe_hw *hw = &adapter->hw;
 
        IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
-                       EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr));
+                       EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param));
 
        ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0);
        ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(0), 0);
@@ -1445,8 +1517,8 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
                srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
                srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
                srrctl |= ((IXGBE_RX_HDR_SIZE <<
-                           IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
-                          IXGBE_SRRCTL_BSIZEHDR_MASK);
+                           IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+                          IXGBE_SRRCTL_BSIZEHDR_MASK);
        } else {
                srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
 
@@ -1463,7 +1535,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
 /**
  * ixgbe_get_skb_hdr - helper function for LRO header processing
  * @skb: pointer to sk_buff to be added to LRO packet
- * @iphdr: pointer to tcp header structure
+ * @iphdr: pointer to ip header structure
  * @tcph: pointer to tcp header structure
  * @hdr_flags: pointer to header flags
  * @priv: private data
@@ -1488,7 +1560,7 @@ static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph,
 }
 
 #define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
-                       (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
+                           (((S) & (PAGE_SIZE - 1)) ? 1 : 0))
 
 /**
  * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
@@ -1514,10 +1586,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        int rx_buf_len;
 
        /* Decide whether to use packet split mode or not */
-       if (netdev->mtu > ETH_DATA_LEN)
-               adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
-       else
-               adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+       adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
 
        /* Set the RX buffer length according to the mode */
        if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
@@ -1638,7 +1707,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
 }
 
 static void ixgbe_vlan_rx_register(struct net_device *netdev,
-                                  struct vlan_group *grp)
+                                   struct vlan_group *grp)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        u32 ctrl;
@@ -1662,14 +1731,16 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
 static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_hw *hw = &adapter->hw;
 
        /* add VID to filter table */
-       ixgbe_set_vfta(&adapter->hw, vid, 0, true);
+       hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true);
 }
 
 static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_hw *hw = &adapter->hw;
 
        if (!test_bit(__IXGBE_DOWN, &adapter->state))
                ixgbe_irq_disable(adapter);
@@ -1680,7 +1751,7 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
                ixgbe_irq_enable(adapter);
 
        /* remove VID from filter table */
-       ixgbe_set_vfta(&adapter->hw, vid, 0, false);
+       hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false);
 }
 
 static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
@@ -1756,15 +1827,15 @@ static void ixgbe_set_rx_mode(struct net_device *netdev)
        addr_count = netdev->uc_count;
        if (addr_count)
                addr_list = netdev->uc_list->dmi_addr;
-       ixgbe_update_uc_addr_list(hw, addr_list, addr_count,
-                                 ixgbe_addr_list_itr);
+       hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count,
+                                         ixgbe_addr_list_itr);
 
        /* reprogram multicast list */
        addr_count = netdev->mc_count;
        if (addr_count)
                addr_list = netdev->mc_list->dmi_addr;
-       ixgbe_update_mc_addr_list(hw, addr_list, addr_count,
-                                 ixgbe_addr_list_itr);
+       hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count,
+                                       ixgbe_addr_list_itr);
 }
 
 static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
@@ -1778,10 +1849,16 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
                q_vectors = 1;
 
        for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+               struct napi_struct *napi;
                q_vector = &adapter->q_vector[q_idx];
                if (!q_vector->rxr_count)
                        continue;
-               napi_enable(&q_vector->napi);
+               napi = &q_vector->napi;
+               if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) &&
+                   (q_vector->rxr_count > 1))
+                       napi->poll = &ixgbe_clean_rxonly_many;
+
+               napi_enable(napi);
        }
 }
 
@@ -1816,7 +1893,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
        ixgbe_configure_rx(adapter);
        for (i = 0; i < adapter->num_rx_queues; i++)
                ixgbe_alloc_rx_buffers(adapter, &adapter->rx_ring[i],
-                                          (adapter->rx_ring[i].count - 1));
+                                      (adapter->rx_ring[i].count - 1));
 }
 
 static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
@@ -1834,7 +1911,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
            (adapter->flags & IXGBE_FLAG_MSI_ENABLED)) {
                if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
                        gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME |
-                               IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
+                               IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD);
                } else {
                        /* MSI only */
                        gpie = 0;
@@ -1897,6 +1974,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 
        /* bring the link up in the watchdog, this could race with our first
         * link up interrupt but shouldn't be a problem */
+       adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE;
+       adapter->link_check_timeout = jiffies;
        mod_timer(&adapter->watchdog_timer, jiffies);
        return 0;
 }
@@ -1921,50 +2000,14 @@ int ixgbe_up(struct ixgbe_adapter *adapter)
 
 void ixgbe_reset(struct ixgbe_adapter *adapter)
 {
-       if (ixgbe_init_hw(&adapter->hw))
-               DPRINTK(PROBE, ERR, "Hardware Error\n");
+       struct ixgbe_hw *hw = &adapter->hw;
+       if (hw->mac.ops.init_hw(hw))
+               dev_err(&adapter->pdev->dev, "Hardware Error\n");
 
        /* reprogram the RAR[0] in case user changed it. */
-       ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
-
-}
-
-#ifdef CONFIG_PM
-static int ixgbe_resume(struct pci_dev *pdev)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       u32 err;
-
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       err = pci_enable_device(pdev);
-       if (err) {
-               printk(KERN_ERR "ixgbe: Cannot enable PCI device from " \
-                               "suspend\n");
-               return err;
-       }
-       pci_set_master(pdev);
-
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
-
-       if (netif_running(netdev)) {
-               err = ixgbe_request_irq(adapter);
-               if (err)
-                       return err;
-       }
-
-       ixgbe_reset(adapter);
-
-       if (netif_running(netdev))
-               ixgbe_up(adapter);
-
-       netif_device_attach(netdev);
+       hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
 
-       return 0;
 }
-#endif
 
 /**
  * ixgbe_clean_rx_ring - Free Rx Buffers per Queue
@@ -1972,7 +2015,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
  * @rx_ring: ring to free buffers from
  **/
 static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
-                               struct ixgbe_ring *rx_ring)
+                                struct ixgbe_ring *rx_ring)
 {
        struct pci_dev *pdev = adapter->pdev;
        unsigned long size;
@@ -1986,8 +2029,8 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
                rx_buffer_info = &rx_ring->rx_buffer_info[i];
                if (rx_buffer_info->dma) {
                        pci_unmap_single(pdev, rx_buffer_info->dma,
-                                        rx_ring->rx_buf_len,
-                                        PCI_DMA_FROMDEVICE);
+                                        rx_ring->rx_buf_len,
+                                        PCI_DMA_FROMDEVICE);
                        rx_buffer_info->dma = 0;
                }
                if (rx_buffer_info->skb) {
@@ -1996,12 +2039,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
                }
                if (!rx_buffer_info->page)
                        continue;
-               pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE,
-                              PCI_DMA_FROMDEVICE);
+               pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2,
+                              PCI_DMA_FROMDEVICE);
                rx_buffer_info->page_dma = 0;
-
                put_page(rx_buffer_info->page);
                rx_buffer_info->page = NULL;
+               rx_buffer_info->page_offset = 0;
        }
 
        size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count;
@@ -2023,7 +2066,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
  * @tx_ring: ring to be cleaned
  **/
 static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter,
-                               struct ixgbe_ring *tx_ring)
+                                struct ixgbe_ring *tx_ring)
 {
        struct ixgbe_tx_buffer *tx_buffer_info;
        unsigned long size;
@@ -2076,33 +2119,43 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter)
 void ixgbe_down(struct ixgbe_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
+       struct ixgbe_hw *hw = &adapter->hw;
        u32 rxctrl;
+       u32 txdctl;
+       int i, j;
 
        /* signal that we are down to the interrupt handler */
        set_bit(__IXGBE_DOWN, &adapter->state);
 
        /* disable receives */
-       rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
-       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL,
-                       rxctrl & ~IXGBE_RXCTRL_RXEN);
+       rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
 
        netif_tx_disable(netdev);
 
-       /* disable transmits in the hardware */
-
-       /* flush both disables */
-       IXGBE_WRITE_FLUSH(&adapter->hw);
+       IXGBE_WRITE_FLUSH(hw);
        msleep(10);
 
+       netif_tx_stop_all_queues(netdev);
+
        ixgbe_irq_disable(adapter);
 
        ixgbe_napi_disable_all(adapter);
+
        del_timer_sync(&adapter->watchdog_timer);
+       cancel_work_sync(&adapter->watchdog_task);
+
+       /* disable transmits in the hardware now that interrupts are off */
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               j = adapter->tx_ring[i].reg_idx;
+               txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j));
+               IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j),
+                               (txdctl & ~IXGBE_TXDCTL_ENABLE));
+       }
 
        netif_carrier_off(netdev);
-       netif_tx_stop_all_queues(netdev);
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
                adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
                dca_remove_requester(&adapter->pdev->dev);
@@ -2114,56 +2167,18 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        ixgbe_clean_all_tx_rings(adapter);
        ixgbe_clean_all_rx_rings(adapter);
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
        /* since we reset the hardware DCA settings were cleared */
        if (dca_add_requester(&adapter->pdev->dev) == 0) {
                adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
                /* always use CB2 mode, difference is masked
                 * in the CB driver */
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
+               IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2);
                ixgbe_setup_dca(adapter);
        }
 #endif
 }
 
-static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct net_device *netdev = pci_get_drvdata(pdev);
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
-#ifdef CONFIG_PM
-       int retval = 0;
-#endif
-
-       netif_device_detach(netdev);
-
-       if (netif_running(netdev)) {
-               ixgbe_down(adapter);
-               ixgbe_free_irq(adapter);
-       }
-
-#ifdef CONFIG_PM
-       retval = pci_save_state(pdev);
-       if (retval)
-               return retval;
-#endif
-
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
-
-       ixgbe_release_hw_control(adapter);
-
-       pci_disable_device(pdev);
-
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
-       return 0;
-}
-
-static void ixgbe_shutdown(struct pci_dev *pdev)
-{
-       ixgbe_suspend(pdev, PMSG_SUSPEND);
-}
-
 /**
  * ixgbe_poll - NAPI Rx polling callback
  * @napi: structure for representing this polling device
@@ -2174,11 +2189,11 @@ static void ixgbe_shutdown(struct pci_dev *pdev)
 static int ixgbe_poll(struct napi_struct *napi, int budget)
 {
        struct ixgbe_q_vector *q_vector = container_of(napi,
-                                         struct ixgbe_q_vector, napi);
+                                                 struct ixgbe_q_vector, napi);
        struct ixgbe_adapter *adapter = q_vector->adapter;
-       int tx_cleaned = 0, work_done = 0;
+       int tx_cleaned, work_done = 0;
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
                ixgbe_update_tx_dca(adapter, adapter->tx_ring);
                ixgbe_update_rx_dca(adapter, adapter->rx_ring);
@@ -2194,12 +2209,11 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
        /* If budget not fully consumed, exit the polling mode */
        if (work_done < budget) {
                netif_rx_complete(adapter->netdev, napi);
-               if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS)
+               if (adapter->itr_setting & 3)
                        ixgbe_set_itr(adapter);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
                        ixgbe_irq_enable(adapter);
        }
-
        return work_done;
 }
 
@@ -2225,8 +2239,48 @@ static void ixgbe_reset_task(struct work_struct *work)
        ixgbe_reinit_locked(adapter);
 }
 
+static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
+{
+       int nrq = 1, ntq = 1;
+       int feature_mask = 0, rss_i, rss_m;
+
+       /* Number of supported queues */
+       switch (adapter->hw.mac.type) {
+       case ixgbe_mac_82598EB:
+               rss_i = adapter->ring_feature[RING_F_RSS].indices;
+               rss_m = 0;
+               feature_mask |= IXGBE_FLAG_RSS_ENABLED;
+
+               switch (adapter->flags & feature_mask) {
+               case (IXGBE_FLAG_RSS_ENABLED):
+                       rss_m = 0xF;
+                       nrq = rss_i;
+                       ntq = rss_i;
+                       break;
+               case 0:
+               default:
+                       rss_i = 0;
+                       rss_m = 0;
+                       nrq = 1;
+                       ntq = 1;
+                       break;
+               }
+
+               adapter->ring_feature[RING_F_RSS].indices = rss_i;
+               adapter->ring_feature[RING_F_RSS].mask = rss_m;
+               break;
+       default:
+               nrq = 1;
+               ntq = 1;
+               break;
+       }
+
+       adapter->num_rx_queues = nrq;
+       adapter->num_tx_queues = ntq;
+}
+
 static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
-                                      int vectors)
+                                       int vectors)
 {
        int err, vector_threshold;
 
@@ -2245,7 +2299,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
         */
        while (vectors >= vector_threshold) {
                err = pci_enable_msix(adapter->pdev, adapter->msix_entries,
-                                     vectors);
+                                     vectors);
                if (!err) /* Success in acquiring all requested vectors. */
                        break;
                else if (err < 0)
@@ -2264,54 +2318,13 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
                kfree(adapter->msix_entries);
                adapter->msix_entries = NULL;
                adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
-               adapter->num_tx_queues = 1;
-               adapter->num_rx_queues = 1;
+               ixgbe_set_num_queues(adapter);
        } else {
                adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
                adapter->num_msix_vectors = vectors;
        }
 }
 
-static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
-{
-       int nrq, ntq;
-       int feature_mask = 0, rss_i, rss_m;
-
-       /* Number of supported queues */
-       switch (adapter->hw.mac.type) {
-       case ixgbe_mac_82598EB:
-               rss_i = adapter->ring_feature[RING_F_RSS].indices;
-               rss_m = 0;
-               feature_mask |= IXGBE_FLAG_RSS_ENABLED;
-
-               switch (adapter->flags & feature_mask) {
-               case (IXGBE_FLAG_RSS_ENABLED):
-                       rss_m = 0xF;
-                       nrq = rss_i;
-                       ntq = rss_i;
-                       break;
-               case 0:
-               default:
-                       rss_i = 0;
-                       rss_m = 0;
-                       nrq = 1;
-                       ntq = 1;
-                       break;
-               }
-
-               adapter->ring_feature[RING_F_RSS].indices = rss_i;
-               adapter->ring_feature[RING_F_RSS].mask = rss_m;
-               break;
-       default:
-               nrq = 1;
-               ntq = 1;
-               break;
-       }
-
-       adapter->num_rx_queues = nrq;
-       adapter->num_tx_queues = ntq;
-}
-
 /**
  * ixgbe_cache_ring_register - Descriptor ring to register mapping
  * @adapter: board private structure to initialize
@@ -2321,9 +2334,6 @@ static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
  **/
 static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
 {
-       /* TODO: Remove all uses of the indices in the cases where multiple
-        *       features are OR'd together, if the feature set makes sense.
-        */
        int feature_mask = 0, rss_i;
        int i, txr_idx, rxr_idx;
 
@@ -2364,21 +2374,22 @@ static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter)
        int i;
 
        adapter->tx_ring = kcalloc(adapter->num_tx_queues,
-                                  sizeof(struct ixgbe_ring), GFP_KERNEL);
+                                  sizeof(struct ixgbe_ring), GFP_KERNEL);
        if (!adapter->tx_ring)
                goto err_tx_ring_allocation;
 
        adapter->rx_ring = kcalloc(adapter->num_rx_queues,
-                                  sizeof(struct ixgbe_ring), GFP_KERNEL);
+                                  sizeof(struct ixgbe_ring), GFP_KERNEL);
        if (!adapter->rx_ring)
                goto err_rx_ring_allocation;
 
        for (i = 0; i < adapter->num_tx_queues; i++) {
-               adapter->tx_ring[i].count = IXGBE_DEFAULT_TXD;
+               adapter->tx_ring[i].count = adapter->tx_ring_count;
                adapter->tx_ring[i].queue_index = i;
        }
+
        for (i = 0; i < adapter->num_rx_queues; i++) {
-               adapter->rx_ring[i].count = IXGBE_DEFAULT_RXD;
+               adapter->rx_ring[i].count = adapter->rx_ring_count;
                adapter->rx_ring[i].queue_index = i;
        }
 
@@ -2400,17 +2411,11 @@ err_tx_ring_allocation:
  * capabilities of the hardware and the kernel.
  **/
 static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
-                                                   *adapter)
+                                                    *adapter)
 {
        int err = 0;
        int vector, v_budget;
 
-       /*
-        * Set the default interrupt throttle rate.
-        */
-       adapter->rx_eitr = (1000000 / IXGBE_DEFAULT_ITR_RX_USECS);
-       adapter->tx_eitr = (1000000 / IXGBE_DEFAULT_ITR_TX_USECS);
-
        /*
         * It's easy to be greedy for MSI-X vectors, but it really
         * doesn't do us much good if we have a lot more vectors
@@ -2418,7 +2423,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
         * (roughly) twice the number of vectors as there are CPU's.
         */
        v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues,
-                      (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
+                      (int)(num_online_cpus() * 2)) + NON_Q_VECTORS;
 
        /*
         * At the same time, hardware can only support a maximum of
@@ -2432,7 +2437,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
        /* A failure in MSI-X entry allocation isn't fatal, but it does
         * mean we disable MSI-X capabilities of the adapter. */
        adapter->msix_entries = kcalloc(v_budget,
-                                       sizeof(struct msix_entry), GFP_KERNEL);
+                                       sizeof(struct msix_entry), GFP_KERNEL);
        if (!adapter->msix_entries) {
                adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
                ixgbe_set_num_queues(adapter);
@@ -2441,7 +2446,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter
                err = ixgbe_alloc_queues(adapter);
                if (err) {
                        DPRINTK(PROBE, ERR, "Unable to allocate memory "
-                                           "for queues\n");
+                               "for queues\n");
                        goto out;
                }
 
@@ -2462,7 +2467,7 @@ try_msi:
                adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
        } else {
                DPRINTK(HW, DEBUG, "Unable to allocate MSI interrupt, "
-                                  "falling back to legacy.  Error: %d\n", err);
+                       "falling back to legacy.  Error: %d\n", err);
                /* reset err */
                err = 0;
        }
@@ -2518,9 +2523,9 @@ static int __devinit ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
        }
 
        DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, "
-                          "Tx Queue count = %u\n",
-               (adapter->num_rx_queues > 1) ? "Enabled" :
-               "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
+               "Tx Queue count = %u\n",
+               (adapter->num_rx_queues > 1) ? "Enabled" :
+               "Disabled", adapter->num_rx_queues, adapter->num_tx_queues);
 
        set_bit(__IXGBE_DOWN, &adapter->state);
 
@@ -2547,15 +2552,19 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
        struct pci_dev *pdev = adapter->pdev;
        unsigned int rss;
 
+       /* PCI config space info */
+
+       hw->vendor_id = pdev->vendor;
+       hw->device_id = pdev->device;
+       hw->revision_id = pdev->revision;
+       hw->subsystem_vendor_id = pdev->subsystem_vendor;
+       hw->subsystem_device_id = pdev->subsystem_device;
+
        /* Set capability flags */
        rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus());
        adapter->ring_feature[RING_F_RSS].indices = rss;
        adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
 
-       /* Enable Dynamic interrupt throttling by default */
-       adapter->rx_eitr = 1;
-       adapter->tx_eitr = 1;
-
        /* default flow control settings */
        hw->fc.original_type = ixgbe_fc_none;
        hw->fc.type = ixgbe_fc_none;
@@ -2566,18 +2575,21 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
 
        /* select 10G link by default */
        hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN;
-       if (hw->mac.ops.reset(hw)) {
-               dev_err(&pdev->dev, "HW Init failed\n");
-               return -EIO;
-       }
-       if (hw->mac.ops.setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true,
-                                        false)) {
-               dev_err(&pdev->dev, "Link Speed setup failed\n");
-               return -EIO;
-       }
+
+       /* enable itr by default in dynamic mode */
+       adapter->itr_setting = 1;
+       adapter->eitr_param = 20000;
+
+       /* set defaults for eitr in MegaBytes */
+       adapter->eitr_low = 10;
+       adapter->eitr_high = 20;
+
+       /* set default ring sizes */
+       adapter->tx_ring_count = IXGBE_DEFAULT_TXD;
+       adapter->rx_ring_count = IXGBE_DEFAULT_RXD;
 
        /* initialize eeprom parameters */
-       if (ixgbe_init_eeprom(hw)) {
+       if (ixgbe_init_eeprom_params_generic(hw)) {
                dev_err(&pdev->dev, "EEPROM initialization failed\n");
                return -EIO;
        }
@@ -2632,6 +2644,31 @@ err:
        return -ENOMEM;
 }
 
+/**
+ * ixgbe_setup_all_tx_resources - allocate all queues Tx resources
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not).  It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
+{
+       int i, err = 0;
+
+       for (i = 0; i < adapter->num_tx_queues; i++) {
+               err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+               if (!err)
+                       continue;
+               DPRINTK(PROBE, ERR, "Allocation for Tx Queue %u failed\n", i);
+               break;
+       }
+
+       return err;
+}
+
 /**
  * ixgbe_setup_rx_resources - allocate Rx resources (Descriptors)
  * @adapter: board private structure
@@ -2640,7 +2677,7 @@ err:
  * Returns 0 on success, negative on failure
  **/
 int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
-                            struct ixgbe_ring *rx_ring)
+                             struct ixgbe_ring *rx_ring)
 {
        struct pci_dev *pdev = adapter->pdev;
        int size;
@@ -2655,7 +2692,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
        rx_ring->rx_buffer_info = vmalloc(size);
        if (!rx_ring->rx_buffer_info) {
                DPRINTK(PROBE, ERR,
-                       "vmalloc allocation failed for the rx desc ring\n");
+                       "vmalloc allocation failed for the rx desc ring\n");
                goto alloc_failed;
        }
        memset(rx_ring->rx_buffer_info, 0, size);
@@ -2668,7 +2705,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter,
 
        if (!rx_ring->desc) {
                DPRINTK(PROBE, ERR,
-                       "Memory allocation failed for the rx desc ring\n");
+                       "Memory allocation failed for the rx desc ring\n");
                vfree(rx_ring->rx_buffer_info);
                goto alloc_failed;
        }
@@ -2684,6 +2721,32 @@ alloc_failed:
        return -ENOMEM;
 }
 
+/**
+ * ixgbe_setup_all_rx_resources - allocate all queues Rx resources
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not).  It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
+{
+       int i, err = 0;
+
+       for (i = 0; i < adapter->num_rx_queues; i++) {
+               err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+               if (!err)
+                       continue;
+               DPRINTK(PROBE, ERR, "Allocation for Rx Queue %u failed\n", i);
+               break;
+       }
+
+       return err;
+}
+
 /**
  * ixgbe_free_tx_resources - Free Tx Resources per Queue
  * @adapter: board private structure
@@ -2691,8 +2754,8 @@ alloc_failed:
  *
  * Free all transmit software resources
  **/
-static void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
-                                    struct ixgbe_ring *tx_ring)
+void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter,
+                             struct ixgbe_ring *tx_ring)
 {
        struct pci_dev *pdev = adapter->pdev;
 
@@ -2727,8 +2790,8 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter)
  *
  * Free all receive software resources
  **/
-static void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
-                                   struct ixgbe_ring *rx_ring)
+void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter,
+                             struct ixgbe_ring *rx_ring)
 {
        struct pci_dev *pdev = adapter->pdev;
 
@@ -2759,59 +2822,6 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter)
                ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]);
 }
 
-/**
- * ixgbe_setup_all_tx_resources - allocate all queues Tx resources
- * @adapter: board private structure
- *
- * If this function returns with an error, then it's possible one or
- * more of the rings is populated (while the rest are not).  It is the
- * callers duty to clean those orphaned rings.
- *
- * Return 0 on success, negative on failure
- **/
-static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter)
-{
-       int i, err = 0;
-
-       for (i = 0; i < adapter->num_tx_queues; i++) {
-               err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]);
-               if (err) {
-                       DPRINTK(PROBE, ERR,
-                               "Allocation for Tx Queue %u failed\n", i);
-                       break;
-               }
-       }
-
-       return err;
-}
-
-/**
- * ixgbe_setup_all_rx_resources - allocate all queues Rx resources
- * @adapter: board private structure
- *
- * If this function returns with an error, then it's possible one or
- * more of the rings is populated (while the rest are not).  It is the
- * callers duty to clean those orphaned rings.
- *
- * Return 0 on success, negative on failure
- **/
-
-static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter)
-{
-       int i, err = 0;
-
-       for (i = 0; i < adapter->num_rx_queues; i++) {
-               err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]);
-               if (err) {
-                       DPRINTK(PROBE, ERR,
-                               "Allocation for Rx Queue %u failed\n", i);
-                       break;
-               }
-       }
-
-       return err;
-}
-
 /**
  * ixgbe_change_mtu - Change the Maximum Transfer Unit
  * @netdev: network interface device structure
@@ -2824,12 +2834,12 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
-       if ((max_frame < (ETH_ZLEN + ETH_FCS_LEN)) ||
-           (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
+       /* MTU < 68 is an error and causes problems on some kernels */
+       if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE))
                return -EINVAL;
 
        DPRINTK(PROBE, INFO, "changing MTU from %d to %d\n",
-               netdev->mtu, new_mtu);
+               netdev->mtu, new_mtu);
        /* must set new MTU before calling down or up */
        netdev->mtu = new_mtu;
 
@@ -2923,6 +2933,135 @@ static int ixgbe_close(struct net_device *netdev)
        return 0;
 }
 
+/**
+ * ixgbe_napi_add_all - prep napi structs for use
+ * @adapter: private struct
+ * helper function to napi_add each possible q_vector->napi
+ */
+static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
+{
+       int q_idx, q_vectors;
+       int (*poll)(struct napi_struct *, int);
+
+       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+               poll = &ixgbe_clean_rxonly;
+               /* Only enable as many vectors as we have rx queues. */
+               q_vectors = adapter->num_rx_queues;
+       } else {
+               poll = &ixgbe_poll;
+               /* only one q_vector for legacy modes */
+               q_vectors = 1;
+       }
+
+       for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+               struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
+               netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
+       }
+}
+
+static void ixgbe_napi_del_all(struct ixgbe_adapter *adapter)
+{
+       int q_idx;
+       int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+
+       /* legacy and MSI only use one vector */
+       if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
+               q_vectors = 1;
+
+       for (q_idx = 0; q_idx < q_vectors; q_idx++) {
+               struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
+               if (!q_vector->rxr_count)
+                       continue;
+               netif_napi_del(&q_vector->napi);
+       }
+}
+
+#ifdef CONFIG_PM
+static int ixgbe_resume(struct pci_dev *pdev)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       u32 err;
+
+       pci_set_power_state(pdev, PCI_D0);
+       pci_restore_state(pdev);
+       err = pci_enable_device(pdev);
+       if (err) {
+               printk(KERN_ERR "ixgbe: Cannot enable PCI device from "
+                               "suspend\n");
+               return err;
+       }
+       pci_set_master(pdev);
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       err = ixgbe_init_interrupt_scheme(adapter);
+       if (err) {
+               printk(KERN_ERR "ixgbe: Cannot initialize interrupts for "
+                               "device\n");
+               return err;
+       }
+
+       ixgbe_napi_add_all(adapter);
+       ixgbe_reset(adapter);
+
+       if (netif_running(netdev)) {
+               err = ixgbe_open(adapter->netdev);
+               if (err)
+                       return err;
+       }
+
+       netif_device_attach(netdev);
+
+       return 0;
+}
+
+#endif /* CONFIG_PM */
+static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct net_device *netdev = pci_get_drvdata(pdev);
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+#ifdef CONFIG_PM
+       int retval = 0;
+#endif
+
+       netif_device_detach(netdev);
+
+       if (netif_running(netdev)) {
+               ixgbe_down(adapter);
+               ixgbe_free_irq(adapter);
+               ixgbe_free_all_tx_resources(adapter);
+               ixgbe_free_all_rx_resources(adapter);
+       }
+       ixgbe_reset_interrupt_capability(adapter);
+       ixgbe_napi_del_all(adapter);
+       kfree(adapter->tx_ring);
+       kfree(adapter->rx_ring);
+
+#ifdef CONFIG_PM
+       retval = pci_save_state(pdev);
+       if (retval)
+               return retval;
+#endif
+
+       pci_enable_wake(pdev, PCI_D3hot, 0);
+       pci_enable_wake(pdev, PCI_D3cold, 0);
+
+       ixgbe_release_hw_control(adapter);
+
+       pci_disable_device(pdev);
+
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
+static void ixgbe_shutdown(struct pci_dev *pdev)
+{
+       ixgbe_suspend(pdev, PMSG_SUSPEND);
+}
+
 /**
  * ixgbe_update_stats - Update the board statistics counters.
  * @adapter: board private structure
@@ -2996,7 +3135,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 
        /* Rx Errors */
        adapter->net_stats.rx_errors = adapter->stats.crcerrs +
-                                               adapter->stats.rlec;
+                                      adapter->stats.rlec;
        adapter->net_stats.rx_dropped = 0;
        adapter->net_stats.rx_length_errors = adapter->stats.rlec;
        adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
@@ -3010,27 +3149,74 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 static void ixgbe_watchdog(unsigned long data)
 {
        struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
-       struct net_device *netdev = adapter->netdev;
-       bool link_up;
-       u32 link_speed = 0;
+       struct ixgbe_hw *hw = &adapter->hw;
 
-       adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up);
+       /* Do the watchdog outside of interrupt context due to the lovely
+        * delays that some of the newer hardware requires */
+       if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+               /* Cause software interrupt to ensure rx rings are cleaned */
+               if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+                       u32 eics =
+                        (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
+                       IXGBE_WRITE_REG(hw, IXGBE_EICS, eics);
+               } else {
+                       /* For legacy and MSI interrupts don't set any bits that
+                        * are enabled for EIAM, because this operation would
+                        * set *both* EIMS and EICS for any bit in EIAM */
+                       IXGBE_WRITE_REG(hw, IXGBE_EICS,
+                                    (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+               }
+               /* Reset the timer */
+               mod_timer(&adapter->watchdog_timer,
+                         round_jiffies(jiffies + 2 * HZ));
+       }
+
+       schedule_work(&adapter->watchdog_task);
+}
+
+/**
+ * ixgbe_watchdog_task - worker thread to bring link up
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_watchdog_task(struct work_struct *work)
+{
+       struct ixgbe_adapter *adapter = container_of(work,
+                                                    struct ixgbe_adapter,
+                                                    watchdog_task);
+       struct net_device *netdev = adapter->netdev;
+       struct ixgbe_hw *hw = &adapter->hw;
+       u32 link_speed = adapter->link_speed;
+       bool link_up = adapter->link_up;
+
+       adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK;
+
+       if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
+               hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+               if (link_up ||
+                   time_after(jiffies, (adapter->link_check_timeout +
+                                        IXGBE_TRY_LINK_TIMEOUT))) {
+                       IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
+                       adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+               }
+               adapter->link_up = link_up;
+               adapter->link_speed = link_speed;
+       }
 
        if (link_up) {
                if (!netif_carrier_ok(netdev)) {
-                       u32 frctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
-                       u32 rmcs = IXGBE_READ_REG(&adapter->hw, IXGBE_RMCS);
+                       u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+                       u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
 #define FLOW_RX (frctl & IXGBE_FCTRL_RFCE)
 #define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X)
                        DPRINTK(LINK, INFO, "NIC Link is Up %s, "
-                               "Flow Control: %s\n",
-                               (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
-                                "10 Gbps" :
-                                (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
-                                 "1 Gbps" : "unknown speed")),
-                               ((FLOW_RX && FLOW_TX) ? "RX/TX" :
-                                (FLOW_RX ? "RX" :
-                                (FLOW_TX ? "TX" : "None"))));
+                               "Flow Control: %s\n",
+                               (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
+                                "10 Gbps" :
+                                (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
+                                 "1 Gbps" : "unknown speed")),
+                               ((FLOW_RX && FLOW_TX) ? "RX/TX" :
+                                (FLOW_RX ? "RX" :
+                                (FLOW_TX ? "TX" : "None"))));
 
                        netif_carrier_on(netdev);
                        netif_tx_wake_all_queues(netdev);
@@ -3039,6 +3225,8 @@ static void ixgbe_watchdog(unsigned long data)
                        adapter->detect_tx_hung = true;
                }
        } else {
+               adapter->link_up = false;
+               adapter->link_speed = 0;
                if (netif_carrier_ok(netdev)) {
                        DPRINTK(LINK, INFO, "NIC Link is Down\n");
                        netif_carrier_off(netdev);
@@ -3047,36 +3235,19 @@ static void ixgbe_watchdog(unsigned long data)
        }
 
        ixgbe_update_stats(adapter);
-
-       if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
-               /* Cause software interrupt to ensure rx rings are cleaned */
-               if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
-                       u32 eics =
-                        (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1;
-                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, eics);
-               } else {
-                       /* for legacy and MSI interrupts don't set any bits that
-                        * are enabled for EIAM, because this operation would
-                        * set *both* EIMS and EICS for any bit in EIAM */
-                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
-                                    (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
-               }
-               /* Reset the timer */
-               mod_timer(&adapter->watchdog_timer,
-                         round_jiffies(jiffies + 2 * HZ));
-       }
+       adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK;
 }
 
 static int ixgbe_tso(struct ixgbe_adapter *adapter,
-                        struct ixgbe_ring *tx_ring, struct sk_buff *skb,
-                        u32 tx_flags, u8 *hdr_len)
+                     struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+                     u32 tx_flags, u8 *hdr_len)
 {
        struct ixgbe_adv_tx_context_desc *context_desc;
        unsigned int i;
        int err;
        struct ixgbe_tx_buffer *tx_buffer_info;
-       u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0;
-       u32 mss_l4len_idx = 0, l4len;
+       u32 vlan_macip_lens = 0, type_tucmd_mlhl;
+       u32 mss_l4len_idx, l4len;
 
        if (skb_is_gso(skb)) {
                if (skb_header_cloned(skb)) {
@@ -3092,16 +3263,16 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
                        iph->tot_len = 0;
                        iph->check = 0;
                        tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-                                                                iph->daddr, 0,
-                                                                IPPROTO_TCP,
-                                                                0);
+                                                                iph->daddr, 0,
+                                                                IPPROTO_TCP,
+                                                                0);
                        adapter->hw_tso_ctxt++;
                } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) {
                        ipv6_hdr(skb)->payload_len = 0;
                        tcp_hdr(skb)->check =
                            ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
-                                            &ipv6_hdr(skb)->daddr,
-                                            0, IPPROTO_TCP, 0);
+                                            &ipv6_hdr(skb)->daddr,
+                                            0, IPPROTO_TCP, 0);
                        adapter->hw_tso6_ctxt++;
                }
 
@@ -3115,7 +3286,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
                        vlan_macip_lens |=
                            (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
                vlan_macip_lens |= ((skb_network_offset(skb)) <<
-                                   IXGBE_ADVTXD_MACLEN_SHIFT);
+                                   IXGBE_ADVTXD_MACLEN_SHIFT);
                *hdr_len += skb_network_offset(skb);
                vlan_macip_lens |=
                    (skb_transport_header(skb) - skb_network_header(skb));
@@ -3125,8 +3296,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
                context_desc->seqnum_seed = 0;
 
                /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */
-               type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
-                                   IXGBE_ADVTXD_DTYP_CTXT);
+               type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT |
+                                  IXGBE_ADVTXD_DTYP_CTXT);
 
                if (skb->protocol == htons(ETH_P_IP))
                        type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
@@ -3134,7 +3305,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
                context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl);
 
                /* MSS L4LEN IDX */
-               mss_l4len_idx |=
+               mss_l4len_idx =
                    (skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT);
                mss_l4len_idx |= (l4len << IXGBE_ADVTXD_L4LEN_SHIFT);
                /* use index 1 for TSO */
@@ -3155,8 +3326,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter,
 }
 
 static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
-                                  struct ixgbe_ring *tx_ring,
-                                  struct sk_buff *skb, u32 tx_flags)
+                          struct ixgbe_ring *tx_ring,
+                          struct sk_buff *skb, u32 tx_flags)
 {
        struct ixgbe_adv_tx_context_desc *context_desc;
        unsigned int i;
@@ -3173,16 +3344,16 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
                        vlan_macip_lens |=
                            (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
                vlan_macip_lens |= (skb_network_offset(skb) <<
-                                   IXGBE_ADVTXD_MACLEN_SHIFT);
+                                   IXGBE_ADVTXD_MACLEN_SHIFT);
                if (skb->ip_summed == CHECKSUM_PARTIAL)
                        vlan_macip_lens |= (skb_transport_header(skb) -
-                                           skb_network_header(skb));
+                                           skb_network_header(skb));
 
                context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens);
                context_desc->seqnum_seed = 0;
 
                type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT |
-                                   IXGBE_ADVTXD_DTYP_CTXT);
+                                   IXGBE_ADVTXD_DTYP_CTXT);
 
                if (skb->ip_summed == CHECKSUM_PARTIAL) {
                        switch (skb->protocol) {
@@ -3190,16 +3361,14 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
                                type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4;
                                if (ip_hdr(skb)->protocol == IPPROTO_TCP)
                                        type_tucmd_mlhl |=
-                                               IXGBE_ADVTXD_TUCMD_L4T_TCP;
+                                               IXGBE_ADVTXD_TUCMD_L4T_TCP;
                                break;
-
                        case __constant_htons(ETH_P_IPV6):
                                /* XXX what about other V6 headers?? */
                                if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
                                        type_tucmd_mlhl |=
-                                               IXGBE_ADVTXD_TUCMD_L4T_TCP;
+                                               IXGBE_ADVTXD_TUCMD_L4T_TCP;
                                break;
-
                        default:
                                if (unlikely(net_ratelimit())) {
                                        DPRINTK(PROBE, WARNING,
@@ -3216,6 +3385,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
 
                tx_buffer_info->time_stamp = jiffies;
                tx_buffer_info->next_to_watch = i;
+
                adapter->hw_csum_tx_good++;
                i++;
                if (i == tx_ring->count)
@@ -3224,12 +3394,13 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
 
                return true;
        }
+
        return false;
 }
 
 static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
-                       struct ixgbe_ring *tx_ring,
-                       struct sk_buff *skb, unsigned int first)
+                        struct ixgbe_ring *tx_ring,
+                        struct sk_buff *skb, unsigned int first)
 {
        struct ixgbe_tx_buffer *tx_buffer_info;
        unsigned int len = skb->len;
@@ -3247,8 +3418,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
 
                tx_buffer_info->length = size;
                tx_buffer_info->dma = pci_map_single(adapter->pdev,
-                                                 skb->data + offset,
-                                                 size, PCI_DMA_TODEVICE);
+                                                    skb->data + offset,
+                                                    size, PCI_DMA_TODEVICE);
                tx_buffer_info->time_stamp = jiffies;
                tx_buffer_info->next_to_watch = i;
 
@@ -3273,9 +3444,10 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
 
                        tx_buffer_info->length = size;
                        tx_buffer_info->dma = pci_map_page(adapter->pdev,
-                                                       frag->page,
-                                                       offset,
-                                                       size, PCI_DMA_TODEVICE);
+                                                          frag->page,
+                                                          offset,
+                                                          size,
+                                                          PCI_DMA_TODEVICE);
                        tx_buffer_info->time_stamp = jiffies;
                        tx_buffer_info->next_to_watch = i;
 
@@ -3298,8 +3470,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
 }
 
 static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
-                              struct ixgbe_ring *tx_ring,
-                              int tx_flags, int count, u32 paylen, u8 hdr_len)
+                           struct ixgbe_ring *tx_ring,
+                           int tx_flags, int count, u32 paylen, u8 hdr_len)
 {
        union ixgbe_adv_tx_desc *tx_desc = NULL;
        struct ixgbe_tx_buffer *tx_buffer_info;
@@ -3318,17 +3490,17 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
                cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE;
 
                olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
-                                               IXGBE_ADVTXD_POPTS_SHIFT;
+                                IXGBE_ADVTXD_POPTS_SHIFT;
 
                /* use index 1 context for tso */
                olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT);
                if (tx_flags & IXGBE_TX_FLAGS_IPV4)
                        olinfo_status |= IXGBE_TXD_POPTS_IXSM <<
-                                               IXGBE_ADVTXD_POPTS_SHIFT;
+                                        IXGBE_ADVTXD_POPTS_SHIFT;
 
        } else if (tx_flags & IXGBE_TX_FLAGS_CSUM)
                olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
-                                               IXGBE_ADVTXD_POPTS_SHIFT;
+                                IXGBE_ADVTXD_POPTS_SHIFT;
 
        olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT);
 
@@ -3338,9 +3510,8 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
                tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
                tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma);
                tx_desc->read.cmd_type_len =
-                       cpu_to_le32(cmd_type_len | tx_buffer_info->length);
+                       cpu_to_le32(cmd_type_len | tx_buffer_info->length);
                tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
-
                i++;
                if (i == tx_ring->count)
                        i = 0;
@@ -3361,7 +3532,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
 }
 
 static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
-                                struct ixgbe_ring *tx_ring, int size)
+                                 struct ixgbe_ring *tx_ring, int size)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
@@ -3377,61 +3548,52 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
                return -EBUSY;
 
        /* A reprieve! - use start_queue because it doesn't call schedule */
-       netif_wake_subqueue(netdev, tx_ring->queue_index);
+       netif_start_subqueue(netdev, tx_ring->queue_index);
        ++adapter->restart_queue;
        return 0;
 }
 
 static int ixgbe_maybe_stop_tx(struct net_device *netdev,
-                              struct ixgbe_ring *tx_ring, int size)
+                              struct ixgbe_ring *tx_ring, int size)
 {
        if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
                return 0;
        return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
 }
 
-
 static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_ring *tx_ring;
-       unsigned int len = skb->len;
        unsigned int first;
        unsigned int tx_flags = 0;
        u8 hdr_len = 0;
        int r_idx = 0, tso;
-       unsigned int mss = 0;
        int count = 0;
        unsigned int f;
-       unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
-       len -= skb->data_len;
+
        r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping;
        tx_ring = &adapter->tx_ring[r_idx];
 
-
-       if (skb->len <= 0) {
-               dev_kfree_skb(skb);
-               return NETDEV_TX_OK;
+       if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
+               tx_flags |= vlan_tx_tag_get(skb);
+               tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
+               tx_flags |= IXGBE_TX_FLAGS_VLAN;
        }
-       mss = skb_shinfo(skb)->gso_size;
-
-       if (mss)
-               count++;
-       else if (skb->ip_summed == CHECKSUM_PARTIAL)
+       /* three things can cause us to need a context descriptor */
+       if (skb_is_gso(skb) ||
+           (skb->ip_summed == CHECKSUM_PARTIAL) ||
+           (tx_flags & IXGBE_TX_FLAGS_VLAN))
                count++;
 
-       count += TXD_USE_COUNT(len);
-       for (f = 0; f < nr_frags; f++)
+       count += TXD_USE_COUNT(skb_headlen(skb));
+       for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
                count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
 
        if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) {
                adapter->tx_busy++;
                return NETDEV_TX_BUSY;
        }
-       if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
-               tx_flags |= IXGBE_TX_FLAGS_VLAN;
-               tx_flags |= (vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT);
-       }
 
        if (skb->protocol == htons(ETH_P_IP))
                tx_flags |= IXGBE_TX_FLAGS_IPV4;
@@ -3445,12 +3607,12 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        if (tso)
                tx_flags |= IXGBE_TX_FLAGS_TSO;
        else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
-                (skb->ip_summed == CHECKSUM_PARTIAL))
+                (skb->ip_summed == CHECKSUM_PARTIAL))
                tx_flags |= IXGBE_TX_FLAGS_CSUM;
 
        ixgbe_tx_queue(adapter, tx_ring, tx_flags,
-                          ixgbe_tx_map(adapter, tx_ring, skb, first),
-                          skb->len, hdr_len);
+                      ixgbe_tx_map(adapter, tx_ring, skb, first),
+                      skb->len, hdr_len);
 
        netdev->trans_start = jiffies;
 
@@ -3484,15 +3646,16 @@ static struct net_device_stats *ixgbe_get_stats(struct net_device *netdev)
 static int ixgbe_set_mac(struct net_device *netdev, void *p)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_hw *hw = &adapter->hw;
        struct sockaddr *addr = p;
 
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-       memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
+       memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
 
-       ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV);
+       hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
 
        return 0;
 }
@@ -3516,28 +3679,19 @@ static void ixgbe_netpoll(struct net_device *netdev)
 #endif
 
 /**
- * ixgbe_napi_add_all - prep napi structs for use
- * @adapter: private struct
- * helper function to napi_add each possible q_vector->napi
- */
-static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
+ * ixgbe_link_config - set up initial link with default speed and duplex
+ * @hw: pointer to private hardware struct
+ *
+ * Returns 0 on success, negative on failure
+ **/
+static int ixgbe_link_config(struct ixgbe_hw *hw)
 {
-       int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
-       int (*poll)(struct napi_struct *, int);
+       u32 autoneg = IXGBE_LINK_SPEED_10GB_FULL;
 
-       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
-               poll = &ixgbe_clean_rxonly;
-       } else {
-               poll = &ixgbe_poll;
-               /* only one q_vector for legacy modes */
-               q_vectors = 1;
-       }
+       /* must always autoneg for both 1G and 10G link */
+       hw->mac.autoneg = true;
 
-       for (i = 0; i < q_vectors; i++) {
-               struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
-               netif_napi_add(adapter->netdev, &q_vector->napi,
-                              (*poll), 64);
-       }
+       return hw->mac.ops.setup_link_speed(hw, autoneg, true, true);
 }
 
 /**
@@ -3552,17 +3706,16 @@ static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
  * and a hardware reset occur.
  **/
 static int __devinit ixgbe_probe(struct pci_dev *pdev,
-                                const struct pci_device_id *ent)
+                                 const struct pci_device_id *ent)
 {
        struct net_device *netdev;
        struct ixgbe_adapter *adapter = NULL;
        struct ixgbe_hw *hw;
        const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
-       unsigned long mmio_start, mmio_len;
        static int cards_found;
        int i, err, pci_using_dac;
        u16 link_status, link_speed, link_width;
-       u32 part_num;
+       u32 part_num, eec;
 
        err = pci_enable_device(pdev);
        if (err)
@@ -3577,7 +3730,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                        err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
                        if (err) {
                                dev_err(&pdev->dev, "No usable DMA "
-                                       "configuration, aborting\n");
+                                       "configuration, aborting\n");
                                goto err_dma;
                        }
                }
@@ -3610,10 +3763,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        hw->back = adapter;
        adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1;
 
-       mmio_start = pci_resource_start(pdev, 0);
-       mmio_len = pci_resource_len(pdev, 0);
-
-       hw->hw_addr = ioremap(mmio_start, mmio_len);
+       hw->hw_addr = ioremap(pci_resource_start(pdev, 0),
+                             pci_resource_len(pdev, 0));
        if (!hw->hw_addr) {
                err = -EIO;
                goto err_ioremap;
@@ -3643,22 +3794,23 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 #endif
        strcpy(netdev->name, pci_name(pdev));
 
-       netdev->mem_start = mmio_start;
-       netdev->mem_end = mmio_start + mmio_len;
-
        adapter->bd_number = cards_found;
 
-       /* PCI config space info */
-       hw->vendor_id = pdev->vendor;
-       hw->device_id = pdev->device;
-       hw->revision_id = pdev->revision;
-       hw->subsystem_vendor_id = pdev->subsystem_vendor;
-       hw->subsystem_device_id = pdev->subsystem_device;
-
        /* Setup hw api */
        memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops));
        hw->mac.type  = ii->mac;
 
+       /* EEPROM */
+       memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops));
+       eec = IXGBE_READ_REG(hw, IXGBE_EEC);
+       /* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */
+       if (!(eec & (1 << 8)))
+               hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic;
+
+       /* PHY */
+       memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
+       /* phy->sfp_type = ixgbe_sfp_type_unknown; */
+
        err = ii->get_invariants(hw);
        if (err)
                goto err_hw_init;
@@ -3668,11 +3820,18 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        if (err)
                goto err_sw_init;
 
+       /* reset_hw fills in the perm_addr as well */
+       err = hw->mac.ops.reset_hw(hw);
+       if (err) {
+               dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err);
+               goto err_sw_init;
+       }
+
        netdev->features = NETIF_F_SG |
-                          NETIF_F_IP_CSUM |
-                          NETIF_F_HW_VLAN_TX |
-                          NETIF_F_HW_VLAN_RX |
-                          NETIF_F_HW_VLAN_FILTER;
+                          NETIF_F_IP_CSUM |
+                          NETIF_F_HW_VLAN_TX |
+                          NETIF_F_HW_VLAN_RX |
+                          NETIF_F_HW_VLAN_FILTER;
 
        netdev->features |= NETIF_F_IPV6_CSUM;
        netdev->features |= NETIF_F_TSO;
@@ -3688,7 +3847,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                netdev->features |= NETIF_F_HIGHDMA;
 
        /* make sure the EEPROM is good */
-       if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) {
+       if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) {
                dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
                err = -EIO;
                goto err_eeprom;
@@ -3697,7 +3856,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        memcpy(netdev->dev_addr, hw->mac.perm_addr, netdev->addr_len);
        memcpy(netdev->perm_addr, hw->mac.perm_addr, netdev->addr_len);
 
-       if (ixgbe_validate_mac_addr(netdev->dev_addr)) {
+       if (ixgbe_validate_mac_addr(netdev->perm_addr)) {
+               dev_err(&pdev->dev, "invalid MAC address\n");
                err = -EIO;
                goto err_eeprom;
        }
@@ -3707,6 +3867,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        adapter->watchdog_timer.data = (unsigned long)adapter;
 
        INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
+       INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task);
 
        err = ixgbe_init_interrupt_scheme(adapter);
        if (err)
@@ -3717,32 +3878,39 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        link_speed = link_status & IXGBE_PCI_LINK_SPEED;
        link_width = link_status & IXGBE_PCI_LINK_WIDTH;
        dev_info(&pdev->dev, "(PCI Express:%s:%s) "
-                "%02x:%02x:%02x:%02x:%02x:%02x\n",
-               ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
-                (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
-                "Unknown"),
-               ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
-                (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
-                (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
-                (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
-                "Unknown"),
-               netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
-               netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
-       ixgbe_read_part_num(hw, &part_num);
+                "%02x:%02x:%02x:%02x:%02x:%02x\n",
+               ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" :
+                (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" :
+                "Unknown"),
+               ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" :
+                (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" :
+                (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" :
+                (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" :
+                "Unknown"),
+               netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
+               netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
+       ixgbe_read_pba_num_generic(hw, &part_num);
        dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
-                hw->mac.type, hw->phy.type,
-                (part_num >> 8), (part_num & 0xff));
+                hw->mac.type, hw->phy.type,
+                (part_num >> 8), (part_num & 0xff));
 
        if (link_width <= IXGBE_PCI_LINK_WIDTH_4) {
                dev_warn(&pdev->dev, "PCI-Express bandwidth available for "
-                        "this card is not sufficient for optimal "
-                        "performance.\n");
+                        "this card is not sufficient for optimal "
+                        "performance.\n");
                dev_warn(&pdev->dev, "For optimal performance a x8 "
-                        "PCI-Express slot is required.\n");
+                        "PCI-Express slot is required.\n");
        }
 
        /* reset the hardware with the new settings */
-       ixgbe_start_hw(hw);
+       hw->mac.ops.start_hw(hw);
+
+       /* link_config depends on start_hw being called at least once */
+       err = ixgbe_link_config(hw);
+       if (err) {
+               dev_err(&pdev->dev, "setup_link_speed FAILED %d\n", err);
+               goto err_register;
+       }
 
        netif_carrier_off(netdev);
        netif_tx_stop_all_queues(netdev);
@@ -3754,7 +3922,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        if (err)
                goto err_register;
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
        if (dca_add_requester(&pdev->dev) == 0) {
                adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
                /* always use CB2 mode, difference is masked
@@ -3804,7 +3972,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 
        flush_scheduled_work();
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
        if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
                adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
                dca_remove_requester(&pdev->dev);
@@ -3822,6 +3990,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
        pci_release_regions(pdev);
 
        DPRINTK(PROBE, INFO, "complete\n");
+       ixgbe_napi_del_all(adapter);
        kfree(adapter->tx_ring);
        kfree(adapter->rx_ring);
 
@@ -3839,7 +4008,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
  * this device has been detected.
  */
 static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
-                                               pci_channel_state_t state)
+                                                pci_channel_state_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct ixgbe_adapter *adapter = netdev->priv;
@@ -3850,7 +4019,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
                ixgbe_down(adapter);
        pci_disable_device(pdev);
 
-       /* Request a slot slot reset. */
+       /* Request a slot reset. */
        return PCI_ERS_RESULT_NEED_RESET;
 }
 
@@ -3867,7 +4036,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
 
        if (pci_enable_device(pdev)) {
                DPRINTK(PROBE, ERR,
-                       "Cannot re-enable PCI device after reset.\n");
+                       "Cannot re-enable PCI device after reset.\n");
                return PCI_ERS_RESULT_DISCONNECT;
        }
        pci_set_master(pdev);
@@ -3901,7 +4070,6 @@ static void ixgbe_io_resume(struct pci_dev *pdev)
        }
 
        netif_device_attach(netdev);
-
 }
 
 static struct pci_error_handlers ixgbe_err_handler = {
@@ -3937,13 +4105,14 @@ static int __init ixgbe_init_module(void)
 
        printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright);
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
        dca_register_notify(&dca_notifier);
 
 #endif
        ret = pci_register_driver(&ixgbe_driver);
        return ret;
 }
+
 module_init(ixgbe_init_module);
 
 /**
@@ -3954,20 +4123,20 @@ module_init(ixgbe_init_module);
  **/
 static void __exit ixgbe_exit_module(void)
 {
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
        dca_unregister_notify(&dca_notifier);
 #endif
        pci_unregister_driver(&ixgbe_driver);
 }
 
-#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE)
+#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE)
 static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event,
-                           void *p)
+                            void *p)
 {
        int ret_val;
 
        ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event,
-                                        __ixgbe_notify_dca);
+                                        __ixgbe_notify_dca);
 
        return ret_val ? NOTIFY_BAD : NOTIFY_DONE;
 }
index 8002931ae82371d62f1f410a28ca0df5ba4746c6..764035a8c9a16b0d0ea99864899747ca2cb8c233 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 #include "ixgbe_common.h"
 #include "ixgbe_phy.h"
 
+static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
 static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
 static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
-static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
-                              u32 device_type, u16 phy_data);
 
 /**
- *  ixgbe_identify_phy - Get physical layer module
+ *  ixgbe_identify_phy_generic - Get physical layer module
  *  @hw: pointer to hardware structure
  *
  *  Determines the physical layer module found on the current adapter.
  **/
-s32 ixgbe_identify_phy(struct ixgbe_hw *hw)
+s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
        u32 phy_addr;
 
-       for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
-               if (ixgbe_validate_phy_addr(hw, phy_addr)) {
-                       hw->phy.addr = phy_addr;
-                       ixgbe_get_phy_id(hw);
-                       hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id);
-                       status = 0;
-                       break;
+       if (hw->phy.type == ixgbe_phy_unknown) {
+               for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
+                       if (ixgbe_validate_phy_addr(hw, phy_addr)) {
+                               hw->phy.addr = phy_addr;
+                               ixgbe_get_phy_id(hw);
+                               hw->phy.type =
+                                       ixgbe_get_phy_type_from_id(hw->phy.id);
+                               status = 0;
+                               break;
+                       }
                }
+       } else {
+               status = 0;
        }
+
        return status;
 }
 
@@ -73,10 +76,8 @@ static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
        bool valid = false;
 
        hw->phy.addr = phy_addr;
-       ixgbe_read_phy_reg(hw,
-                          IXGBE_MDIO_PHY_ID_HIGH,
-                          IXGBE_MDIO_PMA_PMD_DEV_TYPE,
-                          &phy_id);
+       hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
+                            IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
 
        if (phy_id != 0xFFFF && phy_id != 0x0)
                valid = true;
@@ -95,21 +96,18 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
        u16 phy_id_high = 0;
        u16 phy_id_low = 0;
 
-       status = ixgbe_read_phy_reg(hw,
-                                  IXGBE_MDIO_PHY_ID_HIGH,
-                                  IXGBE_MDIO_PMA_PMD_DEV_TYPE,
-                                  &phy_id_high);
+       status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
+                                     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+                                     &phy_id_high);
 
        if (status == 0) {
                hw->phy.id = (u32)(phy_id_high << 16);
-               status = ixgbe_read_phy_reg(hw,
-                                          IXGBE_MDIO_PHY_ID_LOW,
-                                          IXGBE_MDIO_PMA_PMD_DEV_TYPE,
-                                          &phy_id_low);
+               status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
+                                             IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+                                             &phy_id_low);
                hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
                hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
        }
-
        return status;
 }
 
@@ -123,9 +121,6 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
        enum ixgbe_phy_type phy_type;
 
        switch (phy_id) {
-       case TN1010_PHY_ID:
-               phy_type = ixgbe_phy_tn;
-               break;
        case QT2022_PHY_ID:
                phy_type = ixgbe_phy_qt;
                break;
@@ -138,32 +133,31 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id)
 }
 
 /**
- *  ixgbe_reset_phy - Performs a PHY reset
+ *  ixgbe_reset_phy_generic - Performs a PHY reset
  *  @hw: pointer to hardware structure
  **/
-s32 ixgbe_reset_phy(struct ixgbe_hw *hw)
+s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
 {
        /*
         * Perform soft PHY reset to the PHY_XS.
         * This will cause a soft reset to the PHY
         */
-       return ixgbe_write_phy_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
-                                  IXGBE_MDIO_PHY_XS_DEV_TYPE,
-                                  IXGBE_MDIO_PHY_XS_RESET);
+       return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
+                                    IXGBE_MDIO_PHY_XS_DEV_TYPE,
+                                    IXGBE_MDIO_PHY_XS_RESET);
 }
 
 /**
- *  ixgbe_read_phy_reg - Reads a value from a specified PHY register
+ *  ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register
  *  @hw: pointer to hardware structure
  *  @reg_addr: 32 bit address of PHY register to read
  *  @phy_data: Pointer to read data from PHY register
  **/
-s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
-                      u32 device_type, u16 *phy_data)
+s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 *phy_data)
 {
        u32 command;
        u32 i;
-       u32 timeout = 10;
        u32 data;
        s32 status = 0;
        u16 gssr;
@@ -179,9 +173,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
        if (status == 0) {
                /* Setup and write the address cycle command */
                command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
-                          (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-                          (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
-                          (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
+                          (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+                          (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+                          (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
 
                IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
 
@@ -190,7 +184,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
                 * The MDI Command bit will clear when the operation is
                 * complete
                 */
-               for (i = 0; i < timeout; i++) {
+               for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
                        udelay(10);
 
                        command = IXGBE_READ_REG(hw, IXGBE_MSCA);
@@ -210,9 +204,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
                         * command
                         */
                        command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
-                                  (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-                                  (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
-                                  (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
+                                  (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+                                  (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+                                  (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
 
                        IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
 
@@ -221,7 +215,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
                         * completed. The MDI Command bit will clear when the
                         * operation is complete
                         */
-                       for (i = 0; i < timeout; i++) {
+                       for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
                                udelay(10);
 
                                command = IXGBE_READ_REG(hw, IXGBE_MSCA);
@@ -231,8 +225,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
                        }
 
                        if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
-                               hw_dbg(hw,
-                                      "PHY read command didn't complete\n");
+                               hw_dbg(hw, "PHY read command didn't complete\n");
                                status = IXGBE_ERR_PHY;
                        } else {
                                /*
@@ -247,22 +240,22 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
 
                ixgbe_release_swfw_sync(hw, gssr);
        }
+
        return status;
 }
 
 /**
- *  ixgbe_write_phy_reg - Writes a value to specified PHY register
+ *  ixgbe_write_phy_reg_generic - Writes a value to specified PHY register
  *  @hw: pointer to hardware structure
  *  @reg_addr: 32 bit PHY register to write
  *  @device_type: 5 bit device type
  *  @phy_data: Data to write to the PHY register
  **/
-static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
-                              u32 device_type, u16 phy_data)
+s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+                                u32 device_type, u16 phy_data)
 {
        u32 command;
        u32 i;
-       u32 timeout = 10;
        s32 status = 0;
        u16 gssr;
 
@@ -280,9 +273,9 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
 
                /* Setup and write the address cycle command */
                command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
-                          (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-                          (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
-                          (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
+                          (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+                          (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+                          (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
 
                IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
 
@@ -291,19 +284,19 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
                 * The MDI Command bit will clear when the operation is
                 * complete
                 */
-               for (i = 0; i < timeout; i++) {
+               for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
                        udelay(10);
 
                        command = IXGBE_READ_REG(hw, IXGBE_MSCA);
 
-                       if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
-                               hw_dbg(hw, "PHY address cmd didn't complete\n");
+                       if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
                                break;
-                       }
                }
 
-               if ((command & IXGBE_MSCA_MDI_COMMAND) != 0)
+               if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+                       hw_dbg(hw, "PHY address cmd didn't complete\n");
                        status = IXGBE_ERR_PHY;
+               }
 
                if (status == 0) {
                        /*
@@ -311,9 +304,9 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
                         * command
                         */
                        command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
-                                  (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-                                  (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
-                                  (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
+                                  (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
+                                  (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+                                  (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
 
                        IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
 
@@ -322,20 +315,19 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
                         * completed. The MDI Command bit will clear when the
                         * operation is complete
                         */
-                       for (i = 0; i < timeout; i++) {
+                       for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) {
                                udelay(10);
 
                                command = IXGBE_READ_REG(hw, IXGBE_MSCA);
 
-                               if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) {
-                                       hw_dbg(hw, "PHY write command did not "
-                                                 "complete.\n");
+                               if ((command & IXGBE_MSCA_MDI_COMMAND) == 0)
                                        break;
-                               }
                        }
 
-                       if ((command & IXGBE_MSCA_MDI_COMMAND) != 0)
+                       if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) {
+                               hw_dbg(hw, "PHY address cmd didn't complete\n");
                                status = IXGBE_ERR_PHY;
+                       }
                }
 
                ixgbe_release_swfw_sync(hw, gssr);
@@ -345,67 +337,54 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
 }
 
 /**
- *  ixgbe_setup_tnx_phy_link - Set and restart autoneg
+ *  ixgbe_setup_phy_link_generic - Set and restart autoneg
  *  @hw: pointer to hardware structure
  *
  *  Restart autonegotiation and PHY and waits for completion.
  **/
-s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw)
+s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_NOT_IMPLEMENTED;
        u32 time_out;
        u32 max_time_out = 10;
-       u16 autoneg_speed_selection_register = 0x10;
-       u16 autoneg_restart_mask = 0x0200;
-       u16 autoneg_complete_mask = 0x0020;
-       u16 autoneg_reg = 0;
+       u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
 
        /*
         * Set advertisement settings in PHY based on autoneg_advertised
         * settings. If autoneg_advertised = 0, then advertise default values
-        * txn devices cannot be "forced" to a autoneg 10G and fail.  But can
+        * tnx devices cannot be "forced" to a autoneg 10G and fail.  But can
         * for a 1G.
         */
-       ixgbe_read_phy_reg(hw,
-                 autoneg_speed_selection_register,
-                 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                 &autoneg_reg);
+       hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
+                            IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
 
        if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
                autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */
        else
                autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */
 
-       ixgbe_write_phy_reg(hw,
-                 autoneg_speed_selection_register,
-                 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                 autoneg_reg);
-
+       hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
+                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
 
        /* Restart PHY autonegotiation and wait for completion */
-       ixgbe_read_phy_reg(hw,
-                 IXGBE_MDIO_AUTO_NEG_CONTROL,
-                 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                 &autoneg_reg);
+       hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
+                            IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
 
-       autoneg_reg |= autoneg_restart_mask;
+       autoneg_reg |= IXGBE_MII_RESTART;
 
-       ixgbe_write_phy_reg(hw,
-                 IXGBE_MDIO_AUTO_NEG_CONTROL,
-                 IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                 autoneg_reg);
+       hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
+                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
 
        /* Wait for autonegotiation to finish */
        for (time_out = 0; time_out < max_time_out; time_out++) {
                udelay(10);
                /* Restart PHY autonegotiation and wait for completion */
-               status = ixgbe_read_phy_reg(hw,
-                                           IXGBE_MDIO_AUTO_NEG_STATUS,
-                                           IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
-                                           &autoneg_reg);
+               status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
+                                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+                                             &autoneg_reg);
 
-               autoneg_reg &= autoneg_complete_mask;
-               if (autoneg_reg == autoneg_complete_mask) {
+               autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
+               if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
                        status = 0;
                        break;
                }
@@ -418,64 +397,17 @@ s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_check_tnx_phy_link - Determine link and speed status
- *  @hw: pointer to hardware structure
- *
- *  Reads the VS1 register to determine if link is up and the current speed for
- *  the PHY.
- **/
-s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed,
-                            bool *link_up)
-{
-       s32 status = 0;
-       u32 time_out;
-       u32 max_time_out = 10;
-       u16 phy_link = 0;
-       u16 phy_speed = 0;
-       u16 phy_data = 0;
-
-       /* Initialize speed and link to default case */
-       *link_up = false;
-       *speed = IXGBE_LINK_SPEED_10GB_FULL;
-
-       /*
-        * Check current speed and link status of the PHY register.
-        * This is a vendor specific register and may have to
-        * be changed for other copper PHYs.
-        */
-       for (time_out = 0; time_out < max_time_out; time_out++) {
-               udelay(10);
-               if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) {
-                       *link_up = true;
-                       if (phy_speed ==
-                           IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS)
-                               *speed = IXGBE_LINK_SPEED_1GB_FULL;
-                       break;
-               } else {
-                       status = ixgbe_read_phy_reg(hw,
-                                    IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
-                                    IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
-                                    &phy_data);
-                       phy_link = phy_data &
-                               IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
-                       phy_speed = phy_data &
-                               IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS;
-               }
-       }
-
-       return status;
-}
-
-/**
- *  ixgbe_setup_tnx_phy_link_speed - Sets the auto advertised capabilities
+ *  ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
  *  @autoneg: true if autonegotiation enabled
  **/
-s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed,
-                                  bool autoneg,
-                                  bool autoneg_wait_to_complete)
+s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
+                                       ixgbe_link_speed speed,
+                                       bool autoneg,
+                                       bool autoneg_wait_to_complete)
 {
+
        /*
         * Clear autoneg_advertised and set new values based on input link
         * speed.
@@ -484,11 +416,13 @@ s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed,
 
        if (speed & IXGBE_LINK_SPEED_10GB_FULL)
                hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
        if (speed & IXGBE_LINK_SPEED_1GB_FULL)
                hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
 
        /* Setup link based on the new speed settings */
-       ixgbe_setup_tnx_phy_link(hw);
+       hw->phy.ops.setup_link(hw);
 
        return 0;
 }
+
index aa3ea72e678e5d6c849de43db2419eba217d6fe5..9bfe3f2b1d8f499f743890a846790150b9c5757a 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
 #define _IXGBE_PHY_H_
 
 #include "ixgbe_type.h"
+#define IXGBE_I2C_EEPROM_DEV_ADDR    0xA0
 
-s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw);
-s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
-s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
-                              bool autoneg_wait_to_complete);
-s32 ixgbe_identify_phy(struct ixgbe_hw *hw);
-s32 ixgbe_reset_phy(struct ixgbe_hw *hw);
-s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr,
-                              u32 device_type, u16 *phy_data);
-
-/* PHY specific */
-s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw);
-s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up);
-s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg,
-                                 bool autoneg_wait_to_complete);
+/* EEPROM byte offsets */
+#define IXGBE_SFF_IDENTIFIER         0x0
+#define IXGBE_SFF_IDENTIFIER_SFP     0x3
+#define IXGBE_SFF_VENDOR_OUI_BYTE0   0x25
+#define IXGBE_SFF_VENDOR_OUI_BYTE1   0x26
+#define IXGBE_SFF_VENDOR_OUI_BYTE2   0x27
+#define IXGBE_SFF_1GBE_COMP_CODES    0x6
+#define IXGBE_SFF_10GBE_COMP_CODES   0x3
+#define IXGBE_SFF_TRANSMISSION_MEDIA 0x9
+
+/* Bitmasks */
+#define IXGBE_SFF_TWIN_AX_CAPABLE            0x80
+#define IXGBE_SFF_1GBASESX_CAPABLE           0x1
+#define IXGBE_SFF_10GBASESR_CAPABLE          0x10
+#define IXGBE_SFF_10GBASELR_CAPABLE          0x20
+#define IXGBE_I2C_EEPROM_READ_MASK           0x100
+#define IXGBE_I2C_EEPROM_STATUS_MASK         0x3
+#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0
+#define IXGBE_I2C_EEPROM_STATUS_PASS         0x1
+#define IXGBE_I2C_EEPROM_STATUS_FAIL         0x2
+#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS  0x3
+
+/* Bit-shift macros */
+#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT    12
+#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT    8
+#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT    4
+
+/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */
+#define IXGBE_SFF_VENDOR_OUI_TYCO     0x00407600
+#define IXGBE_SFF_VENDOR_OUI_FTL      0x00906500
+#define IXGBE_SFF_VENDOR_OUI_AVAGO    0x00176A00
+
+
+s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw);
+s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw);
+s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw);
+s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+                               u32 device_type, u16 *phy_data);
+s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
+                                u32 device_type, u16 phy_data);
+s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw);
+s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw,
+                                       ixgbe_link_speed speed,
+                                       bool autoneg,
+                                       bool autoneg_wait_to_complete);
 
 #endif /* _IXGBE_PHY_H_ */
index 3e9c483ad8e6f416141baeae2feaf2c61cd8ebdd..c6f8fa1c4e597909065c6189958af703ccfb26b3 100644 (file)
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel 10 Gigabit PCI Express Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 Intel Corporation.
 
   This program is free software; you can redistribute it and/or modify it
   under the terms and conditions of the GNU General Public License,
@@ -20,7 +20,6 @@
   the file called "COPYING".
 
   Contact Information:
-  Linux NICS <linux.nics@intel.com>
   e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
   Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
 
@@ -37,9 +36,9 @@
 /* Device IDs */
 #define IXGBE_DEV_ID_82598AF_DUAL_PORT   0x10C6
 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
-#define IXGBE_DEV_ID_82598AT_DUAL_PORT   0x10C8
 #define IXGBE_DEV_ID_82598EB_CX4         0x10DD
 #define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
+#define IXGBE_DEV_ID_82598EB_XF_LR       0x10F4
 
 /* General Registers */
 #define IXGBE_CTRL      0x00000
 #define IXGBE_EIMC      0x00888
 #define IXGBE_EIAC      0x00810
 #define IXGBE_EIAM      0x00890
-#define IXGBE_EITR(_i) (0x00820 + ((_i) * 4)) /* 0x820-0x86c */
-#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
+#define IXGBE_EITR(_i)  (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : (0x012300 + ((_i) * 4)))
+#define IXGBE_IVAR(_i)  (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */
 #define IXGBE_MSIXT     0x00000 /* MSI-X Table. 0x0000 - 0x01C */
 #define IXGBE_MSIXPBA   0x02000 /* MSI-X Pending bit array */
-#define IXGBE_PBACL     0x11068
+#define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4)))
 #define IXGBE_GPIE      0x00898
 
 /* Flow Control Registers */
 #define IXGBE_TFCS      0x0CE00
 
 /* Receive DMA Registers */
-#define IXGBE_RDBAL(_i) (0x01000 + ((_i) * 0x40)) /* 64 of each (0-63)*/
-#define IXGBE_RDBAH(_i) (0x01004 + ((_i) * 0x40))
-#define IXGBE_RDLEN(_i) (0x01008 + ((_i) * 0x40))
-#define IXGBE_RDH(_i)   (0x01010 + ((_i) * 0x40))
-#define IXGBE_RDT(_i)   (0x01018 + ((_i) * 0x40))
-#define IXGBE_RXDCTL(_i) (0x01028 + ((_i) * 0x40))
-#define IXGBE_RSCCTL(_i) (0x0102C + ((_i) * 0x40))
-#define IXGBE_SRRCTL(_i) (0x02100 + ((_i) * 4))
-                                            /* array of 16 (0x02100-0x0213C) */
-#define IXGBE_DCA_RXCTRL(_i)    (0x02200 + ((_i) * 4))
-                                            /* array of 16 (0x02200-0x0223C) */
-#define IXGBE_RDRXCTL    0x02F00
+#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : (0x0D000 + ((_i - 64) * 0x40)))
+#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : (0x0D004 + ((_i - 64) * 0x40)))
+#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : (0x0D008 + ((_i - 64) * 0x40)))
+#define IXGBE_RDH(_i)   (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : (0x0D010 + ((_i - 64) * 0x40)))
+#define IXGBE_RDT(_i)   (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : (0x0D018 + ((_i - 64) * 0x40)))
+#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : (0x0D028 + ((_i - 64) * 0x40)))
+/*
+ * Split and Replication Receive Control Registers
+ * 00-15 : 0x02100 + n*4
+ * 16-64 : 0x01014 + n*0x40
+ * 64-127: 0x0D014 + (n-64)*0x40
+ */
+#define IXGBE_SRRCTL(_i) (((_i) <= 15) ? (0x02100 + ((_i) * 4)) : \
+                          (((_i) < 64) ? (0x01014 + ((_i) * 0x40)) : \
+                          (0x0D014 + ((_i - 64) * 0x40))))
+/*
+ * Rx DCA Control Register:
+ * 00-15 : 0x02200 + n*4
+ * 16-64 : 0x0100C + n*0x40
+ * 64-127: 0x0D00C + (n-64)*0x40
+ */
+#define IXGBE_DCA_RXCTRL(_i)    (((_i) <= 15) ? (0x02200 + ((_i) * 4)) : \
+                                 (((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \
+                                 (0x0D00C + ((_i - 64) * 0x40))))
+#define IXGBE_RDRXCTL           0x02F00
 #define IXGBE_RXPBSIZE(_i)      (0x03C00 + ((_i) * 4))
-                                            /* 8 of these 0x03C00 - 0x03C1C */
+                                             /* 8 of these 0x03C00 - 0x03C1C */
 #define IXGBE_RXCTRL    0x03000
 #define IXGBE_DROPEN    0x03D04
 #define IXGBE_RXPBSIZE_SHIFT 10
 /* Receive Registers */
 #define IXGBE_RXCSUM    0x05000
 #define IXGBE_RFCTL     0x05008
+#define IXGBE_DRECCCTL  0x02F08
+#define IXGBE_DRECCCTL_DISABLE 0
+/* Multicast Table Array - 128 entries */
 #define IXGBE_MTA(_i)   (0x05200 + ((_i) * 4))
-                                  /* Multicast Table Array - 128 entries */
-#define IXGBE_RAL(_i)   (0x05400 + ((_i) * 8)) /* 16 of these (0-15) */
-#define IXGBE_RAH(_i)   (0x05404 + ((_i) * 8)) /* 16 of these (0-15) */
-#define IXGBE_PSRTYPE   0x05480
-                                  /* 0x5480-0x54BC Packet split receive type */
+#define IXGBE_RAL(_i)   (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x0A200 + ((_i) * 8)))
+#define IXGBE_RAH(_i)   (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x0A204 + ((_i) * 8)))
+/* Packet split receive type */
+#define IXGBE_PSRTYPE(_i)    (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : (0x0EA00 + ((_i) * 4)))
+/* array of 4096 1-bit vlan filters */
 #define IXGBE_VFTA(_i)  (0x0A000 + ((_i) * 4))
-                                        /* array of 4096 1-bit vlan filters */
+/*array of 4096 4-bit vlan vmdq indices */
 #define IXGBE_VFTAVIND(_j, _i)  (0x0A200 + ((_j) * 0x200) + ((_i) * 4))
-                                    /*array of 4096 4-bit vlan vmdq indicies */
 #define IXGBE_FCTRL     0x05080
 #define IXGBE_VLNCTRL   0x05088
 #define IXGBE_MCSTCTRL  0x05090
 #define IXGBE_MRQC      0x05818
-#define IXGBE_VMD_CTL   0x0581C
 #define IXGBE_IMIR(_i)  (0x05A80 + ((_i) * 4))  /* 8 of these (0-7) */
 #define IXGBE_IMIREXT(_i)       (0x05AA0 + ((_i) * 4))  /* 8 of these (0-7) */
 #define IXGBE_IMIRVP    0x05AC0
+#define IXGBE_VMD_CTL   0x0581C
 #define IXGBE_RETA(_i)  (0x05C00 + ((_i) * 4))  /* 32 of these (0-31) */
 #define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4))  /* 10 of these (0-9) */
 
+
 /* Transmit DMA registers */
-#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40))/* 32 of these (0-31)*/
+#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/
 #define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
 #define IXGBE_TDLEN(_i) (0x06008 + ((_i) * 0x40))
 #define IXGBE_TDH(_i)   (0x06010 + ((_i) * 0x40))
 #define IXGBE_TDWBAL(_i) (0x06038 + ((_i) * 0x40))
 #define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40))
 #define IXGBE_DTXCTL    0x07E00
-#define IXGBE_DCA_TXCTRL(_i)    (0x07200 + ((_i) * 4))
-                                             /* there are 16 of these (0-15) */
+
+#define IXGBE_DCA_TXCTRL(_i)    (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */
 #define IXGBE_TIPG      0x0CB00
-#define IXGBE_TXPBSIZE(_i)      (0x0CC00 + ((_i) *0x04))
-                                                     /* there are 8 of these */
+#define IXGBE_TXPBSIZE(_i)      (0x0CC00 + ((_i) * 4)) /* 8 of these */
 #define IXGBE_MNGTXMAP  0x0CD10
 #define IXGBE_TIPG_FIBER_DEFAULT 3
 #define IXGBE_TXPBSIZE_SHIFT    10
 #define IXGBE_IPAV      0x05838
 #define IXGBE_IP4AT     0x05840 /* IPv4 table 0x5840-0x5858 */
 #define IXGBE_IP6AT     0x05880 /* IPv6 table 0x5880-0x588F */
+
 #define IXGBE_WUPL      0x05900
 #define IXGBE_WUPM      0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */
 #define IXGBE_FHFT      0x09000 /* Flex host filter table 9000-93FC */
 #define IXGBE_TDPT2TCCR(_i)     (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */
 #define IXGBE_TDPT2TCSR(_i)     (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */
 
+
+
 /* Stats registers */
 #define IXGBE_CRCERRS   0x04000
 #define IXGBE_ILLERRC   0x04004
 #define IXGBE_XEC       0x04120
 
 #define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) /* 16 of these */
-#define IXGBE_TQSMR(_i) (0x07300 + ((_i) * 4)) /* 8 of these */
+#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : (0x08600 + ((_i) * 4)))
 
 #define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */
 #define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */
 #define IXGBE_DCA_CTRL  0x11074
 
 /* Diagnostic Registers */
-#define IXGBE_RDSTATCTL 0x02C20
-#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
-#define IXGBE_RDHMPN    0x02F08
-#define IXGBE_RIC_DW0   0x02F10
-#define IXGBE_RIC_DW1   0x02F14
-#define IXGBE_RIC_DW2   0x02F18
-#define IXGBE_RIC_DW3   0x02F1C
-#define IXGBE_RDPROBE   0x02F20
-#define IXGBE_TDSTATCTL 0x07C20
-#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
-#define IXGBE_TDHMPN    0x07F08
-#define IXGBE_TIC_DW0   0x07F10
-#define IXGBE_TIC_DW1   0x07F14
-#define IXGBE_TIC_DW2   0x07F18
-#define IXGBE_TIC_DW3   0x07F1C
-#define IXGBE_TDPROBE   0x07F20
-#define IXGBE_TXBUFCTRL 0x0C600
+#define IXGBE_RDSTATCTL   0x02C20
+#define IXGBE_RDSTAT(_i)  (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */
+#define IXGBE_RDHMPN      0x02F08
+#define IXGBE_RIC_DW(_i)  (0x02F10 + ((_i) * 4))
+#define IXGBE_RDPROBE     0x02F20
+#define IXGBE_TDSTATCTL   0x07C20
+#define IXGBE_TDSTAT(_i)  (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */
+#define IXGBE_TDHMPN      0x07F08
+#define IXGBE_TIC_DW(_i)  (0x07F10 + ((_i) * 4))
+#define IXGBE_TDPROBE     0x07F20
+#define IXGBE_TXBUFCTRL   0x0C600
 #define IXGBE_TXBUFDATA0  0x0C610
 #define IXGBE_TXBUFDATA1  0x0C614
 #define IXGBE_TXBUFDATA2  0x0C618
 
 #define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */
 #define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */
-#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* TX Desc writeback RO bit */
+#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */
 #define IXGBE_DCA_MAX_QUEUES_82598   16 /* DCA regs only on 16 queues */
 
 /* MSCA Bit Masks */
 #define IXGBE_MSCA_MDI_IN_PROG_EN    0x80000000 /* MDI in progress enable */
 
 /* MSRWD bit masks */
-#define IXGBE_MSRWD_WRITE_DATA_MASK  0x0000FFFF
-#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0
-#define IXGBE_MSRWD_READ_DATA_MASK   0xFFFF0000
-#define IXGBE_MSRWD_READ_DATA_SHIFT  16
+#define IXGBE_MSRWD_WRITE_DATA_MASK     0x0000FFFF
+#define IXGBE_MSRWD_WRITE_DATA_SHIFT    0
+#define IXGBE_MSRWD_READ_DATA_MASK      0xFFFF0000
+#define IXGBE_MSRWD_READ_DATA_SHIFT     16
 
 /* Atlas registers */
 #define IXGBE_ATLAS_PDN_LPBK    0x24
 #define IXGBE_ATLAS_PDN_TX_1G_QL_ALL    0xF0
 #define IXGBE_ATLAS_PDN_TX_AN_QL_ALL    0xF0
 
+
 /* Device Type definitions for new protocol MDIO commands */
 #define IXGBE_MDIO_PMA_PMD_DEV_TYPE               0x1
 #define IXGBE_MDIO_PCS_DEV_TYPE                   0x3
 #define IXGBE_MDIO_AUTO_NEG_DEV_TYPE              0x7
 #define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE     0x1E   /* Device 30 */
 
+#define IXGBE_MDIO_COMMAND_TIMEOUT     100 /* PHY Timeout for 1 GB mode */
+
 #define IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL      0x0    /* VS1 Control Reg */
 #define IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS       0x1    /* VS1 Status Reg */
 #define IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS  0x0008 /* 1 = Link Up */
 #define IXGBE_MDIO_PHY_XS_RESET        0x8000 /* PHY_XS Reset */
 #define IXGBE_MDIO_PHY_ID_HIGH         0x2 /* PHY ID High Reg*/
 #define IXGBE_MDIO_PHY_ID_LOW          0x3 /* PHY ID Low Reg*/
-#define IXGBE_MDIO_PHY_SPEED_ABILITY   0x4 /* Speed Abilty Reg */
+#define IXGBE_MDIO_PHY_SPEED_ABILITY   0x4 /* Speed Ability Reg */
 #define IXGBE_MDIO_PHY_SPEED_10G       0x0001 /* 10G capable */
 #define IXGBE_MDIO_PHY_SPEED_1G        0x0010 /* 1G capable */
 
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR     0xC30A /* PHY_XS SDA/SCL Address Reg */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA     0xC30B /* PHY_XS SDA/SCL Data Reg */
+#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT     0xC30C /* PHY_XS SDA/SCL Status Reg */
+
+/* MII clause 22/28 definitions */
+#define IXGBE_MDIO_PHY_LOW_POWER_MODE  0x0800
+
+#define IXGBE_MII_SPEED_SELECTION_REG  0x10
+#define IXGBE_MII_RESTART              0x200
+#define IXGBE_MII_AUTONEG_COMPLETE     0x20
+#define IXGBE_MII_AUTONEG_REG          0x0
+
 #define IXGBE_PHY_REVISION_MASK        0xFFFFFFF0
 #define IXGBE_MAX_PHY_ADDR             32
 
 /* PHY IDs*/
-#define TN1010_PHY_ID    0x00A19410
 #define QT2022_PHY_ID    0x0043A400
 
+/* PHY Types */
+#define IXGBE_M88E1145_E_PHY_ID  0x01410CD0
+
 /* General purpose Interrupt Enable */
-#define IXGBE_GPIE_MSIX_MODE      0x00000010 /* MSI-X mode */
-#define IXGBE_GPIE_OCD            0x00000020 /* Other Clear Disable */
-#define IXGBE_GPIE_EIMEN          0x00000040 /* Immediate Interrupt Enable */
-#define IXGBE_GPIE_EIAME          0x40000000
-#define IXGBE_GPIE_PBA_SUPPORT    0x80000000
+#define IXGBE_SDP0_GPIEN         0x00000001 /* SDP0 */
+#define IXGBE_SDP1_GPIEN         0x00000002 /* SDP1 */
+#define IXGBE_GPIE_MSIX_MODE     0x00000010 /* MSI-X mode */
+#define IXGBE_GPIE_OCD           0x00000020 /* Other Clear Disable */
+#define IXGBE_GPIE_EIMEN         0x00000040 /* Immediate Interrupt Enable */
+#define IXGBE_GPIE_EIAME         0x40000000
+#define IXGBE_GPIE_PBA_SUPPORT   0x80000000
 
 /* Transmit Flow Control status */
 #define IXGBE_TFCS_TXOFF         0x00000001
 #define IXGBE_PAP_TXPAUSECNT_MASK   0x0000FFFF /* Pause counter mask */
 
 /* RMCS Bit Masks */
-#define IXGBE_RMCS_RRM          0x00000002 /* Receive Recylce Mode enable */
+#define IXGBE_RMCS_RRM          0x00000002 /* Receive Recycle Mode enable */
 /* Receive Arbitration Control: 0 Round Robin, 1 DFP */
 #define IXGBE_RMCS_RAC          0x00000004
 #define IXGBE_RMCS_DFP          IXGBE_RMCS_RAC /* Deficit Fixed Priority ena */
 #define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority flow control ena */
 #define IXGBE_RMCS_ARBDIS       0x00000040 /* Arbitration disable bit */
 
+
 /* Interrupt register bitmasks */
 
 /* Extended Interrupt Cause Read */
 #define IXGBE_EICR_RTX_QUEUE    0x0000FFFF /* RTx Queue Interrupt */
 #define IXGBE_EICR_LSC          0x00100000 /* Link Status Change */
-#define IXGBE_EICR_MNG          0x00400000 /* Managability Event Interrupt */
+#define IXGBE_EICR_MNG          0x00400000 /* Manageability Event Interrupt */
+#define IXGBE_EICR_GPI_SDP0     0x01000000 /* Gen Purpose Interrupt on SDP0 */
+#define IXGBE_EICR_GPI_SDP1     0x02000000 /* Gen Purpose Interrupt on SDP1 */
 #define IXGBE_EICR_PBUR         0x10000000 /* Packet Buffer Handler Error */
 #define IXGBE_EICR_DHER         0x20000000 /* Descriptor Handler Error */
 #define IXGBE_EICR_TCP_TIMER    0x40000000 /* TCP Timer */
 
 /* Extended Interrupt Cause Set */
 #define IXGBE_EICS_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
-#define IXGBE_EICS_LSC          IXGBE_EICR_LSC /* Link Status Change */
-#define IXGBE_EICR_GPI_SDP0     0x01000000 /* Gen Purpose Interrupt on SDP0 */
-#define IXGBE_EICS_MNG          IXGBE_EICR_MNG /* MNG Event Interrupt */
-#define IXGBE_EICS_PBUR         IXGBE_EICR_PBUR /* Pkt Buf Handler Error */
-#define IXGBE_EICS_DHER         IXGBE_EICR_DHER /* Desc Handler Error */
+#define IXGBE_EICS_LSC          IXGBE_EICR_LSC       /* Link Status Change */
+#define IXGBE_EICS_MNG          IXGBE_EICR_MNG       /* MNG Event Interrupt */
+#define IXGBE_EICS_GPI_SDP0     IXGBE_EICR_GPI_SDP0  /* SDP0 Gen Purpose Int */
+#define IXGBE_EICS_GPI_SDP1     IXGBE_EICR_GPI_SDP1  /* SDP1 Gen Purpose Int */
+#define IXGBE_EICS_PBUR         IXGBE_EICR_PBUR      /* Pkt Buf Handler Err */
+#define IXGBE_EICS_DHER         IXGBE_EICR_DHER      /* Desc Handler Error */
 #define IXGBE_EICS_TCP_TIMER    IXGBE_EICR_TCP_TIMER /* TCP Timer */
 #define IXGBE_EICS_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
 
 #define IXGBE_EIMS_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
 #define IXGBE_EIMS_LSC          IXGBE_EICR_LSC       /* Link Status Change */
 #define IXGBE_EIMS_MNG          IXGBE_EICR_MNG       /* MNG Event Interrupt */
-#define IXGBE_EIMS_PBUR         IXGBE_EICR_PBUR      /* Pkt Buf Handler Error */
+#define IXGBE_EIMS_GPI_SDP0     IXGBE_EICR_GPI_SDP0  /* SDP0 Gen Purpose Int */
+#define IXGBE_EIMS_GPI_SDP1     IXGBE_EICR_GPI_SDP1  /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMS_PBUR         IXGBE_EICR_PBUR      /* Pkt Buf Handler Err */
 #define IXGBE_EIMS_DHER         IXGBE_EICR_DHER      /* Descr Handler Error */
 #define IXGBE_EIMS_TCP_TIMER    IXGBE_EICR_TCP_TIMER /* TCP Timer */
 #define IXGBE_EIMS_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
 #define IXGBE_EIMC_RTX_QUEUE    IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */
 #define IXGBE_EIMC_LSC          IXGBE_EICR_LSC       /* Link Status Change */
 #define IXGBE_EIMC_MNG          IXGBE_EICR_MNG       /* MNG Event Interrupt */
-#define IXGBE_EIMC_PBUR         IXGBE_EICR_PBUR      /* Pkt Buf Handler Error */
-#define IXGBE_EIMC_DHER         IXGBE_EICR_DHER      /* Desc Handler Error */
+#define IXGBE_EIMC_GPI_SDP0     IXGBE_EICR_GPI_SDP0  /* SDP0 Gen Purpose Int */
+#define IXGBE_EIMC_GPI_SDP1     IXGBE_EICR_GPI_SDP1  /* SDP1 Gen Purpose Int */
+#define IXGBE_EIMC_PBUR         IXGBE_EICR_PBUR      /* Pkt Buf Handler Err */
+#define IXGBE_EIMC_DHER         IXGBE_EICR_DHER      /* Desc Handler Err */
 #define IXGBE_EIMC_TCP_TIMER    IXGBE_EICR_TCP_TIMER /* TCP Timer */
 #define IXGBE_EIMC_OTHER        IXGBE_EICR_OTHER     /* INT Cause Active */
 
-#define IXGBE_EIMS_ENABLE_MASK (\
-                               IXGBE_EIMS_RTX_QUEUE       | \
-                               IXGBE_EIMS_LSC             | \
-                               IXGBE_EIMS_TCP_TIMER       | \
-                               IXGBE_EIMS_OTHER)
+#define IXGBE_EIMS_ENABLE_MASK ( \
+                                IXGBE_EIMS_RTX_QUEUE       | \
+                                IXGBE_EIMS_LSC             | \
+                                IXGBE_EIMS_TCP_TIMER       | \
+                                IXGBE_EIMS_OTHER)
 
-/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */
+/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
 #define IXGBE_IMIR_PORT_IM_EN     0x00010000  /* TCP port enable */
 #define IXGBE_IMIR_PORT_BP        0x00020000  /* TCP port check bypass */
 #define IXGBE_IMIREXT_SIZE_BP     0x00001000  /* Packet size bypass */
 #define IXGBE_VLNCTRL_VFE       0x40000000  /* bit 30 */
 #define IXGBE_VLNCTRL_VME       0x80000000  /* bit 31 */
 
+
 #define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100  /* 802.1q protocol */
 
 /* STATUS Bit Masks */
 #define IXGBE_AUTOC_AN_RESTART  0x00001000
 #define IXGBE_AUTOC_FLU         0x00000001
 #define IXGBE_AUTOC_LMS_SHIFT   13
-#define IXGBE_AUTOC_LMS_MASK   (0x7 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN  (0x0 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_1G_AN  (0x2 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN   (0x6 << IXGBE_AUTOC_LMS_SHIFT)
-#define IXGBE_AUTOC_LMS_ATTACH_TYPE    (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
-
-#define IXGBE_AUTOC_1G_PMA_PMD      0x00000200
-#define IXGBE_AUTOC_10G_PMA_PMD     0x00000180
+#define IXGBE_AUTOC_LMS_MASK            (0x7 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN   (0x0 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN  (0x1 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_1G_AN           (0x2 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_AN          (0x4 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN    (0x6 << IXGBE_AUTOC_LMS_SHIFT)
+#define IXGBE_AUTOC_LMS_ATTACH_TYPE     (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
+
+#define IXGBE_AUTOC_1G_PMA_PMD         0x00000200
+#define IXGBE_AUTOC_10G_PMA_PMD        0x00000180
 #define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7
 #define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9
 #define IXGBE_AUTOC_10G_XAUI   (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT)
 #define IXGBE_LINKS_TL_FAULT    0x00001000
 #define IXGBE_LINKS_SIGNAL      0x00000F00
 
+#define IXGBE_LINK_UP_TIME      90 /* 9.0 Seconds */
 #define IXGBE_AUTO_NEG_TIME     45 /* 4.5 Seconds */
 
 /* SW Semaphore Register bitmasks */
 #define IXGBE_PBANUM0_PTR       0x15
 #define IXGBE_PBANUM1_PTR       0x16
 
+/* Legacy EEPROM word offsets */
+#define IXGBE_ISCSI_BOOT_CAPS           0x0033
+#define IXGBE_ISCSI_SETUP_PORT_0        0x0030
+#define IXGBE_ISCSI_SETUP_PORT_1        0x0034
+
 /* EEPROM Commands - SPI */
 #define IXGBE_EEPROM_MAX_RETRY_SPI      5000 /* Max wait 5ms for RDY signal */
 #define IXGBE_EEPROM_STATUS_RDY_SPI     0x01
 #define IXGBE_EEPROM_WRITE_OPCODE_SPI   0x02  /* EEPROM write opcode */
 #define IXGBE_EEPROM_A8_OPCODE_SPI      0x08  /* opcode bit-3 = addr bit-8 */
 #define IXGBE_EEPROM_WREN_OPCODE_SPI    0x06  /* EEPROM set Write Ena latch */
-/* EEPROM reset Write Enbale latch */
+/* EEPROM reset Write Enable latch */
 #define IXGBE_EEPROM_WRDI_OPCODE_SPI    0x04
 #define IXGBE_EEPROM_RDSR_OPCODE_SPI    0x05  /* EEPROM read Status reg */
 #define IXGBE_EEPROM_WRSR_OPCODE_SPI    0x01  /* EEPROM write Status reg */
 /* Number of 100 microseconds we wait for PCI Express master disable */
 #define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800
 
-/* PHY Types */
-#define IXGBE_M88E1145_E_PHY_ID  0x01410CD0
-
 /* Check whether address is multicast.  This is little-endian specific check.*/
 #define IXGBE_IS_MULTICAST(Address) \
-               (bool)(((u8 *)(Address))[0] & ((u8)0x01))
+                (bool)(((u8 *)(Address))[0] & ((u8)0x01))
 
 /* Check whether an address is broadcast. */
 #define IXGBE_IS_BROADCAST(Address)                      \
-               ((((u8 *)(Address))[0] == ((u8)0xff)) && \
-               (((u8 *)(Address))[1] == ((u8)0xff)))
+                ((((u8 *)(Address))[0] == ((u8)0xff)) && \
+                (((u8 *)(Address))[1] == ((u8)0xff)))
 
 /* RAH */
 #define IXGBE_RAH_VIND_MASK     0x003C0000
 #define IXGBE_RAH_VIND_SHIFT    18
 #define IXGBE_RAH_AV            0x80000000
+#define IXGBE_CLEAR_VMDQ_ALL    0xFFFFFFFF
 
 /* Header split receive */
 #define IXGBE_RFCTL_ISCSI_DIS       0x00000001
 #define IXGBE_MAX_FRAME_SZ      0x40040000
 
 #define IXGBE_TDWBAL_HEAD_WB_ENABLE   0x1      /* Tx head write-back enable */
-#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2      /* Tx seq# write-back enable */
+#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2      /* Tx seq# write-back enable */
 
 /* Receive Config masks */
 #define IXGBE_RXCTRL_RXEN       0x00000001  /* Enable Receiver */
 #define IXGBE_FCTRL_BAM 0x00000400 /* Broadcast Accept Mode */
 #define IXGBE_FCTRL_PMCF 0x00001000 /* Pass MAC Control Frames */
 #define IXGBE_FCTRL_DPF 0x00002000 /* Discard Pause Frame */
-/* Receive Priority Flow Control Enbale */
+/* Receive Priority Flow Control Enable */
 #define IXGBE_FCTRL_RPFCE 0x00004000
 #define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */
 
 /* Receive Descriptor bit definitions */
 #define IXGBE_RXD_STAT_DD       0x01    /* Descriptor Done */
 #define IXGBE_RXD_STAT_EOP      0x02    /* End of Packet */
-#define IXGBE_RXD_STAT_IXSM     0x04    /* Ignore checksum */
 #define IXGBE_RXD_STAT_VP       0x08    /* IEEE VLAN Packet */
-#define IXGBE_RXD_STAT_UDPCS    0x10    /* UDP xsum caculated */
+#define IXGBE_RXD_STAT_UDPCS    0x10    /* UDP xsum calculated */
 #define IXGBE_RXD_STAT_L4CS     0x20    /* L4 xsum calculated */
 #define IXGBE_RXD_STAT_IPCS     0x40    /* IP xsum calculated */
 #define IXGBE_RXD_STAT_PIF      0x80    /* passed in-exact filter */
 #define IXGBE_RXD_ERR_USE       0x20    /* Undersize Error */
 #define IXGBE_RXD_ERR_TCPE      0x40    /* TCP/UDP Checksum Error */
 #define IXGBE_RXD_ERR_IPE       0x80    /* IP Checksum Error */
-#define IXGBE_RXDADV_HBO        0x00800000
+#define IXGBE_RXDADV_ERR_HBO    0x00800000 /*Header Buffer Overflow */
 #define IXGBE_RXDADV_ERR_CE     0x01000000 /* CRC Error */
 #define IXGBE_RXDADV_ERR_LE     0x02000000 /* Length Error */
 #define IXGBE_RXDADV_ERR_PE     0x08000000 /* Packet Error */
 #define IXGBE_RXD_CFI_MASK      0x1000  /* CFI is bit 12 */
 #define IXGBE_RXD_CFI_SHIFT     12
 
+
 /* SRRCTL bit definitions */
-#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10     /* so many KBs */
-#define IXGBE_SRRCTL_BSIZEPKT_MASK  0x0000007F
-#define IXGBE_SRRCTL_BSIZEHDR_MASK  0x00003F00
-#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000
+#define IXGBE_SRRCTL_BSIZEPKT_SHIFT     10     /* so many KBs */
+#define IXGBE_SRRCTL_BSIZEPKT_MASK      0x0000007F
+#define IXGBE_SRRCTL_BSIZEHDR_MASK      0x00003F00
+#define IXGBE_SRRCTL_DESCTYPE_LEGACY    0x00000000
 #define IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000
 #define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT  0x04000000
 #define IXGBE_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000
 #define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000
+#define IXGBE_SRRCTL_DESCTYPE_MASK      0x0E000000
 
 #define IXGBE_RXDPS_HDRSTAT_HDRSP       0x00008000
 #define IXGBE_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF
 #define IXGBE_RXDADV_PKTTYPE_UDP        0x00000200 /* UDP hdr present */
 #define IXGBE_RXDADV_PKTTYPE_SCTP       0x00000400 /* SCTP hdr present */
 #define IXGBE_RXDADV_PKTTYPE_NFS        0x00000800 /* NFS hdr present */
-
 /* Masks to determine if packets should be dropped due to frame errors */
-#define IXGBE_RXD_ERR_FRAME_ERR_MASK (\
-                                     IXGBE_RXD_ERR_CE | \
-                                     IXGBE_RXD_ERR_LE | \
-                                     IXGBE_RXD_ERR_PE | \
-                                     IXGBE_RXD_ERR_OSE | \
-                                     IXGBE_RXD_ERR_USE)
-
-#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK (\
-                                     IXGBE_RXDADV_ERR_CE | \
-                                     IXGBE_RXDADV_ERR_LE | \
-                                     IXGBE_RXDADV_ERR_PE | \
-                                     IXGBE_RXDADV_ERR_OSE | \
-                                     IXGBE_RXDADV_ERR_USE)
+#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \
+                                      IXGBE_RXD_ERR_CE | \
+                                      IXGBE_RXD_ERR_LE | \
+                                      IXGBE_RXD_ERR_PE | \
+                                      IXGBE_RXD_ERR_OSE | \
+                                      IXGBE_RXD_ERR_USE)
+
+#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK ( \
+                                      IXGBE_RXDADV_ERR_CE | \
+                                      IXGBE_RXDADV_ERR_LE | \
+                                      IXGBE_RXDADV_ERR_PE | \
+                                      IXGBE_RXDADV_ERR_OSE | \
+                                      IXGBE_RXDADV_ERR_USE)
 
 /* Multicast bit mask */
 #define IXGBE_MCSTCTRL_MFE      0x4
 #define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT  0x000D /* Priority in upper 3 of 16 */
 #define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT  IXGBE_RX_DESC_SPECIAL_PRI_SHIFT
 
+
 /* Transmit Descriptor - Legacy */
 struct ixgbe_legacy_tx_desc {
        u64 buffer_addr;       /* Address of the descriptor's data buffer */
@@ -1008,8 +1052,8 @@ struct ixgbe_legacy_tx_desc {
        union {
                __le32 data;
                struct {
-                       u8 status;     /* Descriptor status */
-                       u8 css;        /* Checksum start */
+                       u8 status;        /* Descriptor status */
+                       u8 css;           /* Checksum start */
                        __le16 vlan;
                } fields;
        } upper;
@@ -1018,7 +1062,7 @@ struct ixgbe_legacy_tx_desc {
 /* Transmit Descriptor - Advanced */
 union ixgbe_adv_tx_desc {
        struct {
-               __le64 buffer_addr;       /* Address of descriptor's data buf */
+               __le64 buffer_addr;      /* Address of descriptor's data buf */
                __le32 cmd_type_len;
                __le32 olinfo_status;
        } read;
@@ -1050,8 +1094,8 @@ union ixgbe_adv_rx_desc {
                        union {
                                __le32 data;
                                struct {
-                                       __le16 pkt_info; /* RSS type, Packet type */
-                                       __le16 hdr_info; /* Split Header, header len */
+                                       __le16 pkt_info; /* RSS, Pkt type */
+                                       __le16 hdr_info; /* Splithdr, hdrlen */
                                } hs_rss;
                        } lo_dword;
                        union {
@@ -1079,49 +1123,69 @@ struct ixgbe_adv_tx_context_desc {
 };
 
 /* Adv Transmit Descriptor Config Masks */
-#define IXGBE_ADVTXD_DTALEN_MASK      0x0000FFFF /* Data buffer length(bytes) */
+#define IXGBE_ADVTXD_DTALEN_MASK      0x0000FFFF /* Data buf length(bytes) */
 #define IXGBE_ADVTXD_DTYP_MASK  0x00F00000 /* DTYP mask */
 #define IXGBE_ADVTXD_DTYP_CTXT  0x00200000 /* Advanced Context Desc */
 #define IXGBE_ADVTXD_DTYP_DATA  0x00300000 /* Advanced Data Descriptor */
 #define IXGBE_ADVTXD_DCMD_EOP   IXGBE_TXD_CMD_EOP  /* End of Packet */
 #define IXGBE_ADVTXD_DCMD_IFCS  IXGBE_TXD_CMD_IFCS /* Insert FCS */
-#define IXGBE_ADVTXD_DCMD_RDMA  0x04000000 /* RDMA */
 #define IXGBE_ADVTXD_DCMD_RS    IXGBE_TXD_CMD_RS   /* Report Status */
-#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000     /* DDP hdr type or iSCSI */
+#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000    /* DDP hdr type or iSCSI */
 #define IXGBE_ADVTXD_DCMD_DEXT  IXGBE_TXD_CMD_DEXT /* Desc ext (1=Adv) */
 #define IXGBE_ADVTXD_DCMD_VLE   IXGBE_TXD_CMD_VLE  /* VLAN pkt enable */
 #define IXGBE_ADVTXD_DCMD_TSE   0x80000000 /* TCP Seg enable */
 #define IXGBE_ADVTXD_STAT_DD    IXGBE_TXD_STAT_DD  /* Descriptor Done */
-#define IXGBE_ADVTXD_STAT_SN_CRC      0x00000002 /* NXTSEQ/SEED present in WB */
+#define IXGBE_ADVTXD_STAT_SN_CRC      0x00000002 /* NXTSEQ/SEED pres in WB */
 #define IXGBE_ADVTXD_STAT_RSV   0x0000000C /* STA Reserved */
 #define IXGBE_ADVTXD_IDX_SHIFT  4 /* Adv desc Index shift */
+#define IXGBE_ADVTXD_CC         0x00000080 /* Check Context */
 #define IXGBE_ADVTXD_POPTS_SHIFT      8  /* Adv desc POPTS shift */
 #define IXGBE_ADVTXD_POPTS_IXSM (IXGBE_TXD_POPTS_IXSM << \
-                               IXGBE_ADVTXD_POPTS_SHIFT)
+                                 IXGBE_ADVTXD_POPTS_SHIFT)
 #define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \
-                               IXGBE_ADVTXD_POPTS_SHIFT)
-#define IXGBE_ADVTXD_POPTS_EOM  0x00000400 /* Enable L bit-RDMA DDP hdr */
-#define IXGBE_ADVTXD_POPTS_ISCO_1ST   0x00000000 /* 1st TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_MDL   0x00000800 /* Middle TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_LAST  0x00001000 /* Last TSO of iSCSI PDU */
-#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU*/
-#define IXGBE_ADVTXD_POPTS_RSV  0x00002000 /* POPTS Reserved */
-#define IXGBE_ADVTXD_PAYLEN_SHIFT  14 /* Adv desc PAYLEN shift */
-#define IXGBE_ADVTXD_MACLEN_SHIFT  9  /* Adv ctxt desc mac len shift */
-#define IXGBE_ADVTXD_VLAN_SHIFT    16  /* Adv ctxt vlan tag shift */
-#define IXGBE_ADVTXD_TUCMD_IPV4    0x00000400  /* IP Packet Type: 1=IPv4 */
-#define IXGBE_ADVTXD_TUCMD_IPV6    0x00000000  /* IP Packet Type: 0=IPv6 */
-#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000  /* L4 Packet TYPE of UDP */
-#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800  /* L4 Packet TYPE of TCP */
-#define IXGBE_ADVTXD_TUCMD_MKRREQ  0x00002000 /* Req requires Markers and CRC */
-#define IXGBE_ADVTXD_L4LEN_SHIFT   8  /* Adv ctxt L4LEN shift */
-#define IXGBE_ADVTXD_MSS_SHIFT     16  /* Adv ctxt MSS shift */
-
+                                 IXGBE_ADVTXD_POPTS_SHIFT)
+#define IXGBE_ADVTXD_POPTS_ISCO_1ST  0x00000000 /* 1st TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_MDL  0x00000800 /* Middle TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU */
+#define IXGBE_ADVTXD_POPTS_RSV       0x00002000 /* POPTS Reserved */
+#define IXGBE_ADVTXD_PAYLEN_SHIFT    14 /* Adv desc PAYLEN shift */
+#define IXGBE_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */
+#define IXGBE_ADVTXD_VLAN_SHIFT      16  /* Adv ctxt vlan tag shift */
+#define IXGBE_ADVTXD_TUCMD_IPV4      0x00000400  /* IP Packet Type: 1=IPv4 */
+#define IXGBE_ADVTXD_TUCMD_IPV6      0x00000000  /* IP Packet Type: 0=IPv6 */
+#define IXGBE_ADVTXD_TUCMD_L4T_UDP   0x00000000  /* L4 Packet TYPE of UDP */
+#define IXGBE_ADVTXD_TUCMD_L4T_TCP   0x00000800  /* L4 Packet TYPE of TCP */
+#define IXGBE_ADVTXD_TUCMD_L4T_SCTP  0x00001000  /* L4 Packet TYPE of SCTP */
+#define IXGBE_ADVTXD_TUCMD_MKRREQ    0x00002000 /*Req requires Markers and CRC*/
+#define IXGBE_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */
+#define IXGBE_ADVTXD_MSS_SHIFT       16  /* Adv ctxt MSS shift */
+
+/* Autonegotiation advertised speeds */
+typedef u32 ixgbe_autoneg_advertised;
 /* Link speed */
+typedef u32 ixgbe_link_speed;
 #define IXGBE_LINK_SPEED_UNKNOWN   0
 #define IXGBE_LINK_SPEED_100_FULL  0x0008
 #define IXGBE_LINK_SPEED_1GB_FULL  0x0020
 #define IXGBE_LINK_SPEED_10GB_FULL 0x0080
+#define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \
+                                        IXGBE_LINK_SPEED_10GB_FULL)
+
+/* Physical layer type */
+typedef u32 ixgbe_physical_layer;
+#define IXGBE_PHYSICAL_LAYER_UNKNOWN      0
+#define IXGBE_PHYSICAL_LAYER_10GBASE_T    0x0001
+#define IXGBE_PHYSICAL_LAYER_1000BASE_T   0x0002
+#define IXGBE_PHYSICAL_LAYER_100BASE_T    0x0004
+#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU  0x0008
+#define IXGBE_PHYSICAL_LAYER_10GBASE_LR   0x0010
+#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM  0x0020
+#define IXGBE_PHYSICAL_LAYER_10GBASE_SR   0x0040
+#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4  0x0080
+#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4  0x0100
+#define IXGBE_PHYSICAL_LAYER_1000BASE_KX  0x0200
+#define IXGBE_PHYSICAL_LAYER_1000BASE_BX  0x0400
 
 
 enum ixgbe_eeprom_type {
@@ -1138,16 +1202,38 @@ enum ixgbe_mac_type {
 
 enum ixgbe_phy_type {
        ixgbe_phy_unknown = 0,
-       ixgbe_phy_tn,
        ixgbe_phy_qt,
-       ixgbe_phy_xaui
+       ixgbe_phy_xaui,
+       ixgbe_phy_tw_tyco,
+       ixgbe_phy_tw_unknown,
+       ixgbe_phy_sfp_avago,
+       ixgbe_phy_sfp_ftl,
+       ixgbe_phy_sfp_unknown,
+       ixgbe_phy_generic
+};
+
+/*
+ * SFP+ module type IDs:
+ *
+ * ID  Module Type
+ * =============
+ * 0   SFP_DA_CU
+ * 1   SFP_SR
+ * 2   SFP_LR
+ */
+enum ixgbe_sfp_type {
+       ixgbe_sfp_type_da_cu = 0,
+       ixgbe_sfp_type_sr = 1,
+       ixgbe_sfp_type_lr = 2,
+       ixgbe_sfp_type_unknown = 0xFFFF
 };
 
 enum ixgbe_media_type {
        ixgbe_media_type_unknown = 0,
        ixgbe_media_type_fiber,
        ixgbe_media_type_copper,
-       ixgbe_media_type_backplane
+       ixgbe_media_type_backplane,
+       ixgbe_media_type_virtual
 };
 
 /* Flow Control Settings */
@@ -1245,59 +1331,114 @@ struct ixgbe_hw;
 typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr,
                                   u32 *vmdq);
 
+/* Function pointer table */
+struct ixgbe_eeprom_operations {
+       s32 (*init_params)(struct ixgbe_hw *);
+       s32 (*read)(struct ixgbe_hw *, u16, u16 *);
+       s32 (*write)(struct ixgbe_hw *, u16, u16);
+       s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
+       s32 (*update_checksum)(struct ixgbe_hw *);
+};
+
 struct ixgbe_mac_operations {
-       s32 (*reset)(struct ixgbe_hw *);
+       s32 (*init_hw)(struct ixgbe_hw *);
+       s32 (*reset_hw)(struct ixgbe_hw *);
+       s32 (*start_hw)(struct ixgbe_hw *);
+       s32 (*clear_hw_cntrs)(struct ixgbe_hw *);
        enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
+       s32 (*get_supported_physical_layer)(struct ixgbe_hw *);
+       s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
+       s32 (*stop_adapter)(struct ixgbe_hw *);
+       s32 (*get_bus_info)(struct ixgbe_hw *);
+       s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*);
+       s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8);
+
+       /* Link */
        s32 (*setup_link)(struct ixgbe_hw *);
-       s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
-       s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
-       s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *);
+       s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
+                               bool);
+       s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool);
+       s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *,
+                                    bool *);
+
+       /* LED */
+       s32 (*led_on)(struct ixgbe_hw *, u32);
+       s32 (*led_off)(struct ixgbe_hw *, u32);
+       s32 (*blink_led_start)(struct ixgbe_hw *, u32);
+       s32 (*blink_led_stop)(struct ixgbe_hw *, u32);
+
+       /* RAR, Multicast, VLAN */
+       s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32);
+       s32 (*clear_rar)(struct ixgbe_hw *, u32);
+       s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
+       s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
+       s32 (*init_rx_addrs)(struct ixgbe_hw *);
+       s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32,
+                                  ixgbe_mc_addr_itr);
+       s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
+                                  ixgbe_mc_addr_itr);
+       s32 (*enable_mc)(struct ixgbe_hw *);
+       s32 (*disable_mc)(struct ixgbe_hw *);
+       s32 (*clear_vfta)(struct ixgbe_hw *);
+       s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
+       s32 (*init_uta_tables)(struct ixgbe_hw *);
+
+       /* Flow Control */
+       s32 (*setup_fc)(struct ixgbe_hw *, s32);
 };
 
 struct ixgbe_phy_operations {
+       s32 (*identify)(struct ixgbe_hw *);
+       s32 (*identify_sfp)(struct ixgbe_hw *);
+       s32 (*reset)(struct ixgbe_hw *);
+       s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
+       s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
        s32 (*setup_link)(struct ixgbe_hw *);
-       s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *);
-       s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool);
-};
-
-struct ixgbe_mac_info {
-       struct ixgbe_mac_operations     ops;
-       enum ixgbe_mac_type             type;
-       u8                              addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
-       u8                              perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
-       s32                             mc_filter_type;
-       u32                             mcft_size;
-       u32                             vft_size;
-       u32                             num_rar_entries;
-       u32                             num_rx_queues;
-       u32                             num_tx_queues;
-       u32                             link_attach_type;
-       u32                             link_mode_select;
-       bool                            link_settings_loaded;
+       s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool,
+                               bool);
+       s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *);
+       s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8);
+       s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *);
+       s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8);
 };
 
 struct ixgbe_eeprom_info {
-       enum ixgbe_eeprom_type          type;
-       u16                             word_size;
-       u16                             address_bits;
+       struct ixgbe_eeprom_operations  ops;
+       enum ixgbe_eeprom_type          type;
+       u32                             semaphore_delay;
+       u16                             word_size;
+       u16                             address_bits;
 };
 
-struct ixgbe_phy_info {
-       struct ixgbe_phy_operations     ops;
-
-       enum ixgbe_phy_type             type;
-       u32                             addr;
-       u32                             id;
-       u32                             revision;
-       enum ixgbe_media_type           media_type;
-       u32                             autoneg_advertised;
-       bool                            autoneg_wait_to_complete;
+struct ixgbe_mac_info {
+       struct ixgbe_mac_operations     ops;
+       enum ixgbe_mac_type             type;
+       u8                              addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+       u8                              perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+       s32                             mc_filter_type;
+       u32                             mcft_size;
+       u32                             vft_size;
+       u32                             num_rar_entries;
+       u32                             max_tx_queues;
+       u32                             max_rx_queues;
+       u32                             link_attach_type;
+       u32                             link_mode_select;
+       bool                            link_settings_loaded;
+       bool                            autoneg;
+       bool                            autoneg_failed;
 };
 
-struct ixgbe_info {
-       enum ixgbe_mac_type             mac;
-       s32                             (*get_invariants)(struct ixgbe_hw *);
-       struct ixgbe_mac_operations     *mac_ops;
+struct ixgbe_phy_info {
+       struct ixgbe_phy_operations     ops;
+       enum ixgbe_phy_type             type;
+       u32                             addr;
+       u32                             id;
+       enum ixgbe_sfp_type             sfp_type;
+       u32                             revision;
+       enum ixgbe_media_type           media_type;
+       bool                            reset_disable;
+       ixgbe_autoneg_advertised        autoneg_advertised;
+       bool                            autoneg_wait_to_complete;
 };
 
 struct ixgbe_hw {
@@ -1316,6 +1457,15 @@ struct ixgbe_hw {
        bool                            adapter_stopped;
 };
 
+struct ixgbe_info {
+       enum ixgbe_mac_type             mac;
+       s32                             (*get_invariants)(struct ixgbe_hw *);
+       struct ixgbe_mac_operations     *mac_ops;
+       struct ixgbe_eeprom_operations  *eeprom_ops;
+       struct ixgbe_phy_operations     *phy_ops;
+};
+
+
 /* Error Codes */
 #define IXGBE_ERR_EEPROM                        -1
 #define IXGBE_ERR_EEPROM_CHECKSUM               -2
@@ -1334,6 +1484,8 @@ struct ixgbe_hw {
 #define IXGBE_ERR_RESET_FAILED                  -15
 #define IXGBE_ERR_SWFW_SYNC                     -16
 #define IXGBE_ERR_PHY_ADDR_INVALID              -17
+#define IXGBE_ERR_I2C                           -18
+#define IXGBE_ERR_SFP_NOT_SUPPORTED             -19
 #define IXGBE_NOT_IMPLEMENTED                   0x7FFFFFFF
 
 #endif /* _IXGBE_TYPE_H_ */
index 0a97c26df6abd848ddc8f09bb97db75cedab1453..a1e22ed1f6ee5616ce9d88bde8a55940dc66fa16 100644 (file)
@@ -41,7 +41,7 @@
 #endif
 
 #if MFE_DEBUG>=1
-#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __FUNCTION__ , ## args)
+#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __func__ , ## args)
 #define MFE_RX_DEBUG 2
 #else
 #define DPRINTK(str,args...)
index 6d343efb2717311c1049d4962e7ae9a1ca042653..4e7a5faf035103a07c3c23b800b0abcfb3bd85fe 100644 (file)
@@ -203,7 +203,7 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
 
 out_badirq:
        printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
-              dev->name, __FUNCTION__, irq);
+              dev->name, __func__, irq);
        return ret;
 }
 
index 096bca54bcf77c33300d43b7e46a7734434378c0..b411b79d72ad136322f8909a0cc3241111918fa5 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <linux/errno.h>
 #include <linux/slab.h>
+#include <linux/mm.h>
 #include <linux/bitmap.h>
 #include <linux/dma-mapping.h>
 #include <linux/vmalloc.h>
index 62071d9c4a557c61a38da5167cf2d017590b5ac7..d1dd5b48dbd1412bddf6321ebd3cceb89d18bacd 100644 (file)
@@ -67,11 +67,10 @@ struct mlx4_mpt_entry {
 #define MLX4_MPT_FLAG_PHYSICAL     (1 <<  9)
 #define MLX4_MPT_FLAG_REGION       (1 <<  8)
 
-#define MLX4_MPT_PD_FLAG_FAST_REG   (1 << 26)
+#define MLX4_MPT_PD_FLAG_FAST_REG   (1 << 27)
+#define MLX4_MPT_PD_FLAG_RAE       (1 << 28)
 #define MLX4_MPT_PD_FLAG_EN_INV            (3 << 24)
 
-#define MLX4_MTT_FLAG_PRESENT          1
-
 #define MLX4_MPT_STATUS_SW             0xF0
 #define MLX4_MPT_STATUS_HW             0x00
 
@@ -348,7 +347,10 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr)
        if (mr->mtt.order >= 0 && mr->mtt.page_shift == 0) {
                /* fast register MR in free state */
                mpt_entry->flags    |= cpu_to_be32(MLX4_MPT_FLAG_FREE);
-               mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_FAST_REG);
+               mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_FAST_REG |
+                                                  MLX4_MPT_PD_FLAG_RAE);
+               mpt_entry->mtt_sz    = cpu_to_be32((1 << mr->mtt.order) *
+                                                  MLX4_MTT_ENTRY_PER_SEG);
        } else {
                mpt_entry->flags    |= cpu_to_be32(MLX4_MPT_FLAG_SW_OWNS);
        }
index 0a18b9e96da152db6c55eaa0026cc578863226eb..372811ade9f5ce3603a56c09a9fce76db80ac85f 100644 (file)
 #include <linux/kernel.h>
 #include <linux/spinlock.h>
 #include <linux/workqueue.h>
-#include <linux/mii.h>
+#include <linux/phy.h>
 #include <linux/mv643xx_eth.h>
 #include <asm/io.h>
 #include <asm/types.h>
 #include <asm/system.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
-static char mv643xx_eth_driver_version[] = "1.3";
+static char mv643xx_eth_driver_version[] = "1.4";
 
-#define MV643XX_ETH_CHECKSUM_OFFLOAD_TX
-#define MV643XX_ETH_NAPI
-#define MV643XX_ETH_TX_FAST_REFILL
-
-#ifdef MV643XX_ETH_CHECKSUM_OFFLOAD_TX
-#define MAX_DESCS_PER_SKB      (MAX_SKB_FRAGS + 1)
-#else
-#define MAX_DESCS_PER_SKB      1
-#endif
 
 /*
  * Registers shared between all ports.
  */
 #define PHY_ADDR                       0x0000
 #define SMI_REG                                0x0004
+#define  SMI_BUSY                      0x10000000
+#define  SMI_READ_VALID                        0x08000000
+#define  SMI_OPCODE_READ               0x04000000
+#define  SMI_OPCODE_WRITE              0x00000000
+#define ERR_INT_CAUSE                  0x0080
+#define  ERR_INT_SMI_DONE              0x00000010
+#define ERR_INT_MASK                   0x0084
 #define WINDOW_BASE(w)                 (0x0200 + ((w) << 3))
 #define WINDOW_SIZE(w)                 (0x0204 + ((w) << 3))
 #define WINDOW_REMAP_HIGH(w)           (0x0280 + ((w) << 2))
@@ -104,16 +102,12 @@ static char mv643xx_eth_driver_version[] = "1.3";
 #define TX_BW_MTU(p)                   (0x0458 + ((p) << 10))
 #define TX_BW_BURST(p)                 (0x045c + ((p) << 10))
 #define INT_CAUSE(p)                   (0x0460 + ((p) << 10))
-#define  INT_TX_END_0                  0x00080000
 #define  INT_TX_END                    0x07f80000
-#define  INT_RX                                0x0007fbfc
+#define  INT_RX                                0x000003fc
 #define  INT_EXT                       0x00000002
 #define INT_CAUSE_EXT(p)               (0x0464 + ((p) << 10))
-#define  INT_EXT_LINK                  0x00100000
-#define  INT_EXT_PHY                   0x00010000
-#define  INT_EXT_TX_ERROR_0            0x00000100
-#define  INT_EXT_TX_0                  0x00000001
-#define  INT_EXT_TX                    0x0000ffff
+#define  INT_EXT_LINK_PHY              0x00110000
+#define  INT_EXT_TX                    0x000000ff
 #define INT_MASK(p)                    (0x0468 + ((p) << 10))
 #define INT_MASK_EXT(p)                        (0x046c + ((p) << 10))
 #define TX_FIFO_URGENT_THRESHOLD(p)    (0x0474 + ((p) << 10))
@@ -171,8 +165,8 @@ static char mv643xx_eth_driver_version[] = "1.3";
 #define FORCE_LINK_PASS                                (1 << 1)
 #define SERIAL_PORT_ENABLE                     (1 << 0)
 
-#define DEFAULT_RX_QUEUE_SIZE          400
-#define DEFAULT_TX_QUEUE_SIZE          800
+#define DEFAULT_RX_QUEUE_SIZE          128
+#define DEFAULT_TX_QUEUE_SIZE          256
 
 
 /*
@@ -249,9 +243,23 @@ struct mv643xx_eth_shared_private {
        void __iomem *base;
 
        /*
-        * Protects access to SMI_REG, which is shared between ports.
+        * Points at the right SMI instance to use.
+        */
+       struct mv643xx_eth_shared_private *smi;
+
+       /*
+        * Provides access to local SMI interface.
         */
-       spinlock_t phy_lock;
+       struct mii_bus smi_bus;
+
+       /*
+        * If we have access to the error interrupt pin (which is
+        * somewhat misnamed as it not only reflects internal errors
+        * but also reflects SMI completion), use that to wait for
+        * SMI access completion instead of polling the SMI busy bit.
+        */
+       int err_interrupt;
+       wait_queue_head_t smi_busy_wait;
 
        /*
         * Per-port MBUS window access register value.
@@ -263,9 +271,13 @@ struct mv643xx_eth_shared_private {
         */
        unsigned int t_clk;
        int extended_rx_coal_limit;
-       int tx_bw_control_moved;
+       int tx_bw_control;
 };
 
+#define TX_BW_CONTROL_ABSENT           0
+#define TX_BW_CONTROL_OLD_LAYOUT       1
+#define TX_BW_CONTROL_NEW_LAYOUT       2
+
 
 /* per-port *****************************************************************/
 struct mib_counters {
@@ -314,8 +326,6 @@ struct rx_queue {
        dma_addr_t rx_desc_dma;
        int rx_desc_area_size;
        struct sk_buff **rx_skb;
-
-       struct timer_list rx_oom;
 };
 
 struct tx_queue {
@@ -330,7 +340,12 @@ struct tx_queue {
        struct tx_desc *tx_desc_area;
        dma_addr_t tx_desc_dma;
        int tx_desc_area_size;
-       struct sk_buff **tx_skb;
+
+       struct sk_buff_head tx_skb;
+
+       unsigned long tx_packets;
+       unsigned long tx_bytes;
+       unsigned long tx_dropped;
 };
 
 struct mv643xx_eth_private {
@@ -339,14 +354,24 @@ struct mv643xx_eth_private {
 
        struct net_device *dev;
 
-       struct mv643xx_eth_shared_private *shared_smi;
-       int phy_addr;
-
-       spinlock_t lock;
+       struct phy_device *phy;
 
+       struct timer_list mib_counters_timer;
+       spinlock_t mib_counters_lock;
        struct mib_counters mib_counters;
+
        struct work_struct tx_timeout_task;
-       struct mii_if_info mii;
+
+       struct napi_struct napi;
+       u8 work_link;
+       u8 work_tx;
+       u8 work_tx_end;
+       u8 work_rx;
+       u8 work_rx_refill;
+       u8 work_rx_oom;
+
+       int skb_size;
+       struct sk_buff_head rx_recycle;
 
        /*
         * RX state.
@@ -354,9 +379,8 @@ struct mv643xx_eth_private {
        int default_rx_ring_size;
        unsigned long rx_desc_sram_addr;
        int rx_desc_sram_size;
-       u8 rxq_mask;
-       int rxq_primary;
-       struct napi_struct napi;
+       int rxq_count;
+       struct timer_list rx_oom;
        struct rx_queue rxq[8];
 
        /*
@@ -365,12 +389,8 @@ struct mv643xx_eth_private {
        int default_tx_ring_size;
        unsigned long tx_desc_sram_addr;
        int tx_desc_sram_size;
-       u8 txq_mask;
-       int txq_primary;
+       int txq_count;
        struct tx_queue txq[8];
-#ifdef MV643XX_ETH_TX_FAST_REFILL
-       int tx_clean_threshold;
-#endif
 };
 
 
@@ -440,94 +460,21 @@ static void txq_disable(struct tx_queue *txq)
                udelay(10);
 }
 
-static void __txq_maybe_wake(struct tx_queue *txq)
+static void txq_maybe_wake(struct tx_queue *txq)
 {
        struct mv643xx_eth_private *mp = txq_to_mp(txq);
+       struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);
 
-       /*
-        * netif_{stop,wake}_queue() flow control only applies to
-        * the primary queue.
-        */
-       BUG_ON(txq->index != mp->txq_primary);
-
-       if (txq->tx_ring_size - txq->tx_desc_count >= MAX_DESCS_PER_SKB)
-               netif_wake_queue(mp->dev);
-}
-
-
-/* rx ***********************************************************************/
-static void txq_reclaim(struct tx_queue *txq, int force);
-
-static void rxq_refill(struct rx_queue *rxq)
-{
-       struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
-       unsigned long flags;
-
-       spin_lock_irqsave(&mp->lock, flags);
-
-       while (rxq->rx_desc_count < rxq->rx_ring_size) {
-               int skb_size;
-               struct sk_buff *skb;
-               int unaligned;
-               int rx;
-
-               /*
-                * Reserve 2+14 bytes for an ethernet header (the
-                * hardware automatically prepends 2 bytes of dummy
-                * data to each received packet), 16 bytes for up to
-                * four VLAN tags, and 4 bytes for the trailing FCS
-                * -- 36 bytes total.
-                */
-               skb_size = mp->dev->mtu + 36;
-
-               /*
-                * Make sure that the skb size is a multiple of 8
-                * bytes, as the lower three bits of the receive
-                * descriptor's buffer size field are ignored by
-                * the hardware.
-                */
-               skb_size = (skb_size + 7) & ~7;
-
-               skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1);
-               if (skb == NULL)
-                       break;
-
-               unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
-               if (unaligned)
-                       skb_reserve(skb, dma_get_cache_alignment() - unaligned);
-
-               rxq->rx_desc_count++;
-               rx = rxq->rx_used_desc;
-               rxq->rx_used_desc = (rx + 1) % rxq->rx_ring_size;
-
-               rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data,
-                                               skb_size, DMA_FROM_DEVICE);
-               rxq->rx_desc_area[rx].buf_size = skb_size;
-               rxq->rx_skb[rx] = skb;
-               wmb();
-               rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA |
-                                               RX_ENABLE_INTERRUPT;
-               wmb();
-
-               /*
-                * The hardware automatically prepends 2 bytes of
-                * dummy data to each received packet, so that the
-                * IP header ends up 16-byte aligned.
-                */
-               skb_reserve(skb, 2);
+       if (netif_tx_queue_stopped(nq)) {
+               __netif_tx_lock(nq, smp_processor_id());
+               if (txq->tx_ring_size - txq->tx_desc_count >= MAX_SKB_FRAGS + 1)
+                       netif_tx_wake_queue(nq);
+               __netif_tx_unlock(nq);
        }
-
-       if (rxq->rx_desc_count != rxq->rx_ring_size)
-               mod_timer(&rxq->rx_oom, jiffies + (HZ / 10));
-
-       spin_unlock_irqrestore(&mp->lock, flags);
 }
 
-static inline void rxq_refill_timer_wrapper(unsigned long data)
-{
-       rxq_refill((struct rx_queue *)data);
-}
 
+/* rx napi ******************************************************************/
 static int rxq_process(struct rx_queue *rxq, int budget)
 {
        struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
@@ -539,31 +486,31 @@ static int rxq_process(struct rx_queue *rxq, int budget)
                struct rx_desc *rx_desc;
                unsigned int cmd_sts;
                struct sk_buff *skb;
-               unsigned long flags;
-
-               spin_lock_irqsave(&mp->lock, flags);
+               u16 byte_cnt;
 
                rx_desc = &rxq->rx_desc_area[rxq->rx_curr_desc];
 
                cmd_sts = rx_desc->cmd_sts;
-               if (cmd_sts & BUFFER_OWNED_BY_DMA) {
-                       spin_unlock_irqrestore(&mp->lock, flags);
+               if (cmd_sts & BUFFER_OWNED_BY_DMA)
                        break;
-               }
                rmb();
 
                skb = rxq->rx_skb[rxq->rx_curr_desc];
                rxq->rx_skb[rxq->rx_curr_desc] = NULL;
 
-               rxq->rx_curr_desc = (rxq->rx_curr_desc + 1) % rxq->rx_ring_size;
+               rxq->rx_curr_desc++;
+               if (rxq->rx_curr_desc == rxq->rx_ring_size)
+                       rxq->rx_curr_desc = 0;
 
-               spin_unlock_irqrestore(&mp->lock, flags);
-
-               dma_unmap_single(NULL, rx_desc->buf_ptr + 2,
+               dma_unmap_single(NULL, rx_desc->buf_ptr,
                                 rx_desc->buf_size, DMA_FROM_DEVICE);
                rxq->rx_desc_count--;
                rx++;
 
+               mp->work_rx_refill |= 1 << rxq->index;
+
+               byte_cnt = rx_desc->byte_cnt;
+
                /*
                 * Update statistics.
                 *
@@ -573,7 +520,7 @@ static int rxq_process(struct rx_queue *rxq, int budget)
                 * byte CRC at the end of the packet (which we do count).
                 */
                stats->rx_packets++;
-               stats->rx_bytes += rx_desc->byte_cnt - 2;
+               stats->rx_bytes += byte_cnt - 2;
 
                /*
                 * In case we received a packet without first / last bits
@@ -596,72 +543,84 @@ static int rxq_process(struct rx_queue *rxq, int budget)
                        if (cmd_sts & ERROR_SUMMARY)
                                stats->rx_errors++;
 
-                       dev_kfree_skb_irq(skb);
+                       dev_kfree_skb(skb);
                } else {
                        /*
                         * The -4 is for the CRC in the trailer of the
                         * received packet
                         */
-                       skb_put(skb, rx_desc->byte_cnt - 2 - 4);
+                       skb_put(skb, byte_cnt - 2 - 4);
 
-                       if (cmd_sts & LAYER_4_CHECKSUM_OK) {
+                       if (cmd_sts & LAYER_4_CHECKSUM_OK)
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
-                               skb->csum = htons(
-                                       (cmd_sts & 0x0007fff8) >> 3);
-                       }
                        skb->protocol = eth_type_trans(skb, mp->dev);
-#ifdef MV643XX_ETH_NAPI
                        netif_receive_skb(skb);
-#else
-                       netif_rx(skb);
-#endif
                }
 
                mp->dev->last_rx = jiffies;
        }
 
-       rxq_refill(rxq);
+       if (rx < budget)
+               mp->work_rx &= ~(1 << rxq->index);
 
        return rx;
 }
 
-#ifdef MV643XX_ETH_NAPI
-static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
+static int rxq_refill(struct rx_queue *rxq, int budget)
 {
-       struct mv643xx_eth_private *mp;
-       int rx;
-       int i;
+       struct mv643xx_eth_private *mp = rxq_to_mp(rxq);
+       int refilled;
 
-       mp = container_of(napi, struct mv643xx_eth_private, napi);
+       refilled = 0;
+       while (refilled < budget && rxq->rx_desc_count < rxq->rx_ring_size) {
+               struct sk_buff *skb;
+               int unaligned;
+               int rx;
+
+               skb = __skb_dequeue(&mp->rx_recycle);
+               if (skb == NULL)
+                       skb = dev_alloc_skb(mp->skb_size +
+                                           dma_get_cache_alignment() - 1);
 
-#ifdef MV643XX_ETH_TX_FAST_REFILL
-       if (++mp->tx_clean_threshold > 5) {
-               mp->tx_clean_threshold = 0;
-               for (i = 0; i < 8; i++)
-                       if (mp->txq_mask & (1 << i))
-                               txq_reclaim(mp->txq + i, 0);
-
-               if (netif_carrier_ok(mp->dev)) {
-                       spin_lock_irq(&mp->lock);
-                       __txq_maybe_wake(mp->txq + mp->txq_primary);
-                       spin_unlock_irq(&mp->lock);
+               if (skb == NULL) {
+                       mp->work_rx_oom |= 1 << rxq->index;
+                       goto oom;
                }
-       }
-#endif
 
-       rx = 0;
-       for (i = 7; rx < budget && i >= 0; i--)
-               if (mp->rxq_mask & (1 << i))
-                       rx += rxq_process(mp->rxq + i, budget - rx);
+               unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
+               if (unaligned)
+                       skb_reserve(skb, dma_get_cache_alignment() - unaligned);
 
-       if (rx < budget) {
-               netif_rx_complete(mp->dev, napi);
-               wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
+               refilled++;
+               rxq->rx_desc_count++;
+
+               rx = rxq->rx_used_desc++;
+               if (rxq->rx_used_desc == rxq->rx_ring_size)
+                       rxq->rx_used_desc = 0;
+
+               rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data,
+                                               mp->skb_size, DMA_FROM_DEVICE);
+               rxq->rx_desc_area[rx].buf_size = mp->skb_size;
+               rxq->rx_skb[rx] = skb;
+               wmb();
+               rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA |
+                                               RX_ENABLE_INTERRUPT;
+               wmb();
+
+               /*
+                * The hardware automatically prepends 2 bytes of
+                * dummy data to each received packet, so that the
+                * IP header ends up 16-byte aligned.
+                */
+               skb_reserve(skb, 2);
        }
 
-       return rx;
+       if (refilled < budget)
+               mp->work_rx_refill &= ~(1 << rxq->index);
+
+oom:
+       return refilled;
 }
-#endif
 
 
 /* tx ***********************************************************************/
@@ -684,8 +643,9 @@ static int txq_alloc_desc_index(struct tx_queue *txq)
 
        BUG_ON(txq->tx_desc_count >= txq->tx_ring_size);
 
-       tx_desc_curr = txq->tx_curr_desc;
-       txq->tx_curr_desc = (tx_desc_curr + 1) % txq->tx_ring_size;
+       tx_desc_curr = txq->tx_curr_desc++;
+       if (txq->tx_curr_desc == txq->tx_ring_size)
+               txq->tx_curr_desc = 0;
 
        BUG_ON(txq->tx_curr_desc == txq->tx_used_desc);
 
@@ -714,10 +674,8 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb)
                        desc->cmd_sts = BUFFER_OWNED_BY_DMA |
                                        ZERO_PADDING | TX_LAST_DESC |
                                        TX_ENABLE_INTERRUPT;
-                       txq->tx_skb[tx_index] = skb;
                } else {
                        desc->cmd_sts = BUFFER_OWNED_BY_DMA;
-                       txq->tx_skb[tx_index] = NULL;
                }
 
                desc->l4i_chk = 0;
@@ -734,144 +692,228 @@ static inline __be16 sum16_as_be(__sum16 sum)
        return (__force __be16)sum;
 }
 
-static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
+static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
 {
        struct mv643xx_eth_private *mp = txq_to_mp(txq);
        int nr_frags = skb_shinfo(skb)->nr_frags;
        int tx_index;
        struct tx_desc *desc;
        u32 cmd_sts;
+       u16 l4i_chk;
        int length;
 
        cmd_sts = TX_FIRST_DESC | GEN_CRC | BUFFER_OWNED_BY_DMA;
-
-       tx_index = txq_alloc_desc_index(txq);
-       desc = &txq->tx_desc_area[tx_index];
-
-       if (nr_frags) {
-               txq_submit_frag_skb(txq, skb);
-
-               length = skb_headlen(skb);
-               txq->tx_skb[tx_index] = NULL;
-       } else {
-               cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT;
-               length = skb->len;
-               txq->tx_skb[tx_index] = skb;
-       }
-
-       desc->byte_cnt = length;
-       desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
+       l4i_chk = 0;
 
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
-               int mac_hdr_len;
+               int tag_bytes;
 
                BUG_ON(skb->protocol != htons(ETH_P_IP) &&
                       skb->protocol != htons(ETH_P_8021Q));
 
-               cmd_sts |= GEN_TCP_UDP_CHECKSUM |
-                          GEN_IP_V4_CHECKSUM   |
-                          ip_hdr(skb)->ihl << TX_IHL_SHIFT;
+               tag_bytes = (void *)ip_hdr(skb) - (void *)skb->data - ETH_HLEN;
+               if (unlikely(tag_bytes & ~12)) {
+                       if (skb_checksum_help(skb) == 0)
+                               goto no_csum;
+                       kfree_skb(skb);
+                       return 1;
+               }
 
-               mac_hdr_len = (void *)ip_hdr(skb) - (void *)skb->data;
-               switch (mac_hdr_len - ETH_HLEN) {
-               case 0:
-                       break;
-               case 4:
+               if (tag_bytes & 4)
                        cmd_sts |= MAC_HDR_EXTRA_4_BYTES;
-                       break;
-               case 8:
+               if (tag_bytes & 8)
                        cmd_sts |= MAC_HDR_EXTRA_8_BYTES;
-                       break;
-               case 12:
-                       cmd_sts |= MAC_HDR_EXTRA_4_BYTES;
-                       cmd_sts |= MAC_HDR_EXTRA_8_BYTES;
-                       break;
-               default:
-                       if (net_ratelimit())
-                               dev_printk(KERN_ERR, &txq_to_mp(txq)->dev->dev,
-                                  "mac header length is %d?!\n", mac_hdr_len);
-                       break;
-               }
+
+               cmd_sts |= GEN_TCP_UDP_CHECKSUM |
+                          GEN_IP_V4_CHECKSUM   |
+                          ip_hdr(skb)->ihl << TX_IHL_SHIFT;
 
                switch (ip_hdr(skb)->protocol) {
                case IPPROTO_UDP:
                        cmd_sts |= UDP_FRAME;
-                       desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
+                       l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
                        break;
                case IPPROTO_TCP:
-                       desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
+                       l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
                        break;
                default:
                        BUG();
                }
        } else {
+no_csum:
                /* Errata BTS #50, IHL must be 5 if no HW checksum */
                cmd_sts |= 5 << TX_IHL_SHIFT;
-               desc->l4i_chk = 0;
        }
 
+       tx_index = txq_alloc_desc_index(txq);
+       desc = &txq->tx_desc_area[tx_index];
+
+       if (nr_frags) {
+               txq_submit_frag_skb(txq, skb);
+               length = skb_headlen(skb);
+       } else {
+               cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT;
+               length = skb->len;
+       }
+
+       desc->l4i_chk = l4i_chk;
+       desc->byte_cnt = length;
+       desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
+
+       __skb_queue_tail(&txq->tx_skb, skb);
+
        /* ensure all other descriptors are written before first cmd_sts */
        wmb();
        desc->cmd_sts = cmd_sts;
 
-       /* clear TX_END interrupt status */
-       wrl(mp, INT_CAUSE(mp->port_num), ~(INT_TX_END_0 << txq->index));
-       rdl(mp, INT_CAUSE(mp->port_num));
+       /* clear TX_END status */
+       mp->work_tx_end &= ~(1 << txq->index);
 
        /* ensure all descriptors are written before poking hardware */
        wmb();
        txq_enable(txq);
 
        txq->tx_desc_count += nr_frags + 1;
+
+       return 0;
 }
 
 static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
-       struct net_device_stats *stats = &dev->stats;
+       int queue;
        struct tx_queue *txq;
-       unsigned long flags;
+       struct netdev_queue *nq;
+
+       queue = skb_get_queue_mapping(skb);
+       txq = mp->txq + queue;
+       nq = netdev_get_tx_queue(dev, queue);
 
        if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) {
-               stats->tx_dropped++;
+               txq->tx_dropped++;
                dev_printk(KERN_DEBUG, &dev->dev,
                           "failed to linearize skb with tiny "
                           "unaligned fragment\n");
                return NETDEV_TX_BUSY;
        }
 
-       spin_lock_irqsave(&mp->lock, flags);
-
-       txq = mp->txq + mp->txq_primary;
-
-       if (txq->tx_ring_size - txq->tx_desc_count < MAX_DESCS_PER_SKB) {
-               spin_unlock_irqrestore(&mp->lock, flags);
-               if (txq->index == mp->txq_primary && net_ratelimit())
-                       dev_printk(KERN_ERR, &dev->dev,
-                                  "primary tx queue full?!\n");
+       if (txq->tx_ring_size - txq->tx_desc_count < MAX_SKB_FRAGS + 1) {
+               if (net_ratelimit())
+                       dev_printk(KERN_ERR, &dev->dev, "tx queue full?!\n");
                kfree_skb(skb);
                return NETDEV_TX_OK;
        }
 
-       txq_submit_skb(txq, skb);
-       stats->tx_bytes += skb->len;
-       stats->tx_packets++;
-       dev->trans_start = jiffies;
-
-       if (txq->index == mp->txq_primary) {
+       if (!txq_submit_skb(txq, skb)) {
                int entries_left;
 
+               txq->tx_bytes += skb->len;
+               txq->tx_packets++;
+               dev->trans_start = jiffies;
+
                entries_left = txq->tx_ring_size - txq->tx_desc_count;
-               if (entries_left < MAX_DESCS_PER_SKB)
-                       netif_stop_queue(dev);
+               if (entries_left < MAX_SKB_FRAGS + 1)
+                       netif_tx_stop_queue(nq);
        }
 
-       spin_unlock_irqrestore(&mp->lock, flags);
-
        return NETDEV_TX_OK;
 }
 
 
+/* tx napi ******************************************************************/
+static void txq_kick(struct tx_queue *txq)
+{
+       struct mv643xx_eth_private *mp = txq_to_mp(txq);
+       struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);
+       u32 hw_desc_ptr;
+       u32 expected_ptr;
+
+       __netif_tx_lock(nq, smp_processor_id());
+
+       if (rdl(mp, TXQ_COMMAND(mp->port_num)) & (1 << txq->index))
+               goto out;
+
+       hw_desc_ptr = rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, txq->index));
+       expected_ptr = (u32)txq->tx_desc_dma +
+                               txq->tx_curr_desc * sizeof(struct tx_desc);
+
+       if (hw_desc_ptr != expected_ptr)
+               txq_enable(txq);
+
+out:
+       __netif_tx_unlock(nq);
+
+       mp->work_tx_end &= ~(1 << txq->index);
+}
+
+static int txq_reclaim(struct tx_queue *txq, int budget, int force)
+{
+       struct mv643xx_eth_private *mp = txq_to_mp(txq);
+       struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index);
+       int reclaimed;
+
+       __netif_tx_lock(nq, smp_processor_id());
+
+       reclaimed = 0;
+       while (reclaimed < budget && txq->tx_desc_count > 0) {
+               int tx_index;
+               struct tx_desc *desc;
+               u32 cmd_sts;
+               struct sk_buff *skb;
+
+               tx_index = txq->tx_used_desc;
+               desc = &txq->tx_desc_area[tx_index];
+               cmd_sts = desc->cmd_sts;
+
+               if (cmd_sts & BUFFER_OWNED_BY_DMA) {
+                       if (!force)
+                               break;
+                       desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA;
+               }
+
+               txq->tx_used_desc = tx_index + 1;
+               if (txq->tx_used_desc == txq->tx_ring_size)
+                       txq->tx_used_desc = 0;
+
+               reclaimed++;
+               txq->tx_desc_count--;
+
+               skb = NULL;
+               if (cmd_sts & TX_LAST_DESC)
+                       skb = __skb_dequeue(&txq->tx_skb);
+
+               if (cmd_sts & ERROR_SUMMARY) {
+                       dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n");
+                       mp->dev->stats.tx_errors++;
+               }
+
+               if (cmd_sts & TX_FIRST_DESC) {
+                       dma_unmap_single(NULL, desc->buf_ptr,
+                                        desc->byte_cnt, DMA_TO_DEVICE);
+               } else {
+                       dma_unmap_page(NULL, desc->buf_ptr,
+                                      desc->byte_cnt, DMA_TO_DEVICE);
+               }
+
+               if (skb != NULL) {
+                       if (skb_queue_len(&mp->rx_recycle) <
+                                       mp->default_rx_ring_size &&
+                           skb_recycle_check(skb, mp->skb_size))
+                               __skb_queue_head(&mp->rx_recycle, skb);
+                       else
+                               dev_kfree_skb(skb);
+               }
+       }
+
+       __netif_tx_unlock(nq);
+
+       if (reclaimed < budget)
+               mp->work_tx &= ~(1 << txq->index);
+
+       return reclaimed;
+}
+
+
 /* tx rate control **********************************************************/
 /*
  * Set total maximum TX rate (shared by all TX queues for this port)
@@ -895,14 +937,17 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst)
        if (bucket_size > 65535)
                bucket_size = 65535;
 
-       if (mp->shared->tx_bw_control_moved) {
-               wrl(mp, TX_BW_RATE_MOVED(mp->port_num), token_rate);
-               wrl(mp, TX_BW_MTU_MOVED(mp->port_num), mtu);
-               wrl(mp, TX_BW_BURST_MOVED(mp->port_num), bucket_size);
-       } else {
+       switch (mp->shared->tx_bw_control) {
+       case TX_BW_CONTROL_OLD_LAYOUT:
                wrl(mp, TX_BW_RATE(mp->port_num), token_rate);
                wrl(mp, TX_BW_MTU(mp->port_num), mtu);
                wrl(mp, TX_BW_BURST(mp->port_num), bucket_size);
+               break;
+       case TX_BW_CONTROL_NEW_LAYOUT:
+               wrl(mp, TX_BW_RATE_MOVED(mp->port_num), token_rate);
+               wrl(mp, TX_BW_MTU_MOVED(mp->port_num), mtu);
+               wrl(mp, TX_BW_BURST_MOVED(mp->port_num), bucket_size);
+               break;
        }
 }
 
@@ -934,14 +979,21 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq)
        /*
         * Turn on fixed priority mode.
         */
-       if (mp->shared->tx_bw_control_moved)
-               off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);
-       else
+       off = 0;
+       switch (mp->shared->tx_bw_control) {
+       case TX_BW_CONTROL_OLD_LAYOUT:
                off = TXQ_FIX_PRIO_CONF(mp->port_num);
+               break;
+       case TX_BW_CONTROL_NEW_LAYOUT:
+               off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);
+               break;
+       }
 
-       val = rdl(mp, off);
-       val |= 1 << txq->index;
-       wrl(mp, off, val);
+       if (off) {
+               val = rdl(mp, off);
+               val |= 1 << txq->index;
+               wrl(mp, off, val);
+       }
 }
 
 static void txq_set_wrr(struct tx_queue *txq, int weight)
@@ -953,95 +1005,147 @@ static void txq_set_wrr(struct tx_queue *txq, int weight)
        /*
         * Turn off fixed priority mode.
         */
-       if (mp->shared->tx_bw_control_moved)
-               off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);
-       else
+       off = 0;
+       switch (mp->shared->tx_bw_control) {
+       case TX_BW_CONTROL_OLD_LAYOUT:
                off = TXQ_FIX_PRIO_CONF(mp->port_num);
+               break;
+       case TX_BW_CONTROL_NEW_LAYOUT:
+               off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num);
+               break;
+       }
 
-       val = rdl(mp, off);
-       val &= ~(1 << txq->index);
-       wrl(mp, off, val);
+       if (off) {
+               val = rdl(mp, off);
+               val &= ~(1 << txq->index);
+               wrl(mp, off, val);
 
-       /*
-        * Configure WRR weight for this queue.
-        */
-       off = TXQ_BW_WRR_CONF(mp->port_num, txq->index);
+               /*
+                * Configure WRR weight for this queue.
+                */
+               off = TXQ_BW_WRR_CONF(mp->port_num, txq->index);
 
-       val = rdl(mp, off);
-       val = (val & ~0xff) | (weight & 0xff);
-       wrl(mp, off, val);
+               val = rdl(mp, off);
+               val = (val & ~0xff) | (weight & 0xff);
+               wrl(mp, off, val);
+       }
 }
 
 
 /* mii management interface *************************************************/
-#define SMI_BUSY               0x10000000
-#define SMI_READ_VALID         0x08000000
-#define SMI_OPCODE_READ                0x04000000
-#define SMI_OPCODE_WRITE       0x00000000
+static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id)
+{
+       struct mv643xx_eth_shared_private *msp = dev_id;
 
-static void smi_reg_read(struct mv643xx_eth_private *mp, unsigned int addr,
-                        unsigned int reg, unsigned int *value)
+       if (readl(msp->base + ERR_INT_CAUSE) & ERR_INT_SMI_DONE) {
+               writel(~ERR_INT_SMI_DONE, msp->base + ERR_INT_CAUSE);
+               wake_up(&msp->smi_busy_wait);
+               return IRQ_HANDLED;
+       }
+
+       return IRQ_NONE;
+}
+
+static int smi_is_done(struct mv643xx_eth_shared_private *msp)
 {
-       void __iomem *smi_reg = mp->shared_smi->base + SMI_REG;
-       unsigned long flags;
-       int i;
+       return !(readl(msp->base + SMI_REG) & SMI_BUSY);
+}
 
-       /* the SMI register is a shared resource */
-       spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
+static int smi_wait_ready(struct mv643xx_eth_shared_private *msp)
+{
+       if (msp->err_interrupt == NO_IRQ) {
+               int i;
 
-       /* wait for the SMI register to become available */
-       for (i = 0; readl(smi_reg) & SMI_BUSY; i++) {
-               if (i == 1000) {
-                       printk("%s: PHY busy timeout\n", mp->dev->name);
-                       goto out;
+               for (i = 0; !smi_is_done(msp); i++) {
+                       if (i == 10)
+                               return -ETIMEDOUT;
+                       msleep(10);
                }
-               udelay(10);
+
+               return 0;
+       }
+
+       if (!wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp),
+                               msecs_to_jiffies(100)))
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static int smi_bus_read(struct mii_bus *bus, int addr, int reg)
+{
+       struct mv643xx_eth_shared_private *msp = bus->priv;
+       void __iomem *smi_reg = msp->base + SMI_REG;
+       int ret;
+
+       if (smi_wait_ready(msp)) {
+               printk("mv643xx_eth: SMI bus busy timeout\n");
+               return -ETIMEDOUT;
        }
 
        writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg);
 
-       /* now wait for the data to be valid */
-       for (i = 0; !(readl(smi_reg) & SMI_READ_VALID); i++) {
-               if (i == 1000) {
-                       printk("%s: PHY read timeout\n", mp->dev->name);
-                       goto out;
-               }
-               udelay(10);
+       if (smi_wait_ready(msp)) {
+               printk("mv643xx_eth: SMI bus busy timeout\n");
+               return -ETIMEDOUT;
        }
 
-       *value = readl(smi_reg) & 0xffff;
-out:
-       spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
+       ret = readl(smi_reg);
+       if (!(ret & SMI_READ_VALID)) {
+               printk("mv643xx_eth: SMI bus read not valid\n");
+               return -ENODEV;
+       }
+
+       return ret & 0xffff;
 }
 
-static void smi_reg_write(struct mv643xx_eth_private *mp,
-                         unsigned int addr,
-                         unsigned int reg, unsigned int value)
+static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val)
 {
-       void __iomem *smi_reg = mp->shared_smi->base + SMI_REG;
-       unsigned long flags;
-       int i;
+       struct mv643xx_eth_shared_private *msp = bus->priv;
+       void __iomem *smi_reg = msp->base + SMI_REG;
 
-       /* the SMI register is a shared resource */
-       spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
-
-       /* wait for the SMI register to become available */
-       for (i = 0; readl(smi_reg) & SMI_BUSY; i++) {
-               if (i == 1000) {
-                       printk("%s: PHY busy timeout\n", mp->dev->name);
-                       goto out;
-               }
-               udelay(10);
+       if (smi_wait_ready(msp)) {
+               printk("mv643xx_eth: SMI bus busy timeout\n");
+               return -ETIMEDOUT;
        }
 
        writel(SMI_OPCODE_WRITE | (reg << 21) |
-               (addr << 16) | (value & 0xffff), smi_reg);
-out:
-       spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
+               (addr << 16) | (val & 0xffff), smi_reg);
+
+       if (smi_wait_ready(msp)) {
+               printk("mv643xx_eth: SMI bus busy timeout\n");
+               return -ETIMEDOUT;
+       }
+
+       return 0;
 }
 
 
-/* mib counters *************************************************************/
+/* statistics ***************************************************************/
+static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
+{
+       struct mv643xx_eth_private *mp = netdev_priv(dev);
+       struct net_device_stats *stats = &dev->stats;
+       unsigned long tx_packets = 0;
+       unsigned long tx_bytes = 0;
+       unsigned long tx_dropped = 0;
+       int i;
+
+       for (i = 0; i < mp->txq_count; i++) {
+               struct tx_queue *txq = mp->txq + i;
+
+               tx_packets += txq->tx_packets;
+               tx_bytes += txq->tx_bytes;
+               tx_dropped += txq->tx_dropped;
+       }
+
+       stats->tx_packets = tx_packets;
+       stats->tx_bytes = tx_bytes;
+       stats->tx_dropped = tx_dropped;
+
+       return stats;
+}
+
 static inline u32 mib_read(struct mv643xx_eth_private *mp, int offset)
 {
        return rdl(mp, MIB_COUNTERS(mp->port_num) + offset);
@@ -1059,6 +1163,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
 {
        struct mib_counters *p = &mp->mib_counters;
 
+       spin_lock(&mp->mib_counters_lock);
        p->good_octets_received += mib_read(mp, 0x00);
        p->good_octets_received += (u64)mib_read(mp, 0x04) << 32;
        p->bad_octets_received += mib_read(mp, 0x08);
@@ -1091,6 +1196,16 @@ static void mib_counters_update(struct mv643xx_eth_private *mp)
        p->bad_crc_event += mib_read(mp, 0x74);
        p->collision += mib_read(mp, 0x78);
        p->late_collision += mib_read(mp, 0x7c);
+       spin_unlock(&mp->mib_counters_lock);
+
+       mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ);
+}
+
+static void mib_counters_timer_wrapper(unsigned long _mp)
+{
+       struct mv643xx_eth_private *mp = (void *)_mp;
+
+       mib_counters_update(mp);
 }
 
 
@@ -1156,9 +1271,9 @@ static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *
        struct mv643xx_eth_private *mp = netdev_priv(dev);
        int err;
 
-       spin_lock_irq(&mp->lock);
-       err = mii_ethtool_gset(&mp->mii, cmd);
-       spin_unlock_irq(&mp->lock);
+       err = phy_read_status(mp->phy);
+       if (err == 0)
+               err = phy_ethtool_gset(mp->phy, cmd);
 
        /*
         * The MAC does not support 1000baseT_Half.
@@ -1206,18 +1321,13 @@ static int mv643xx_eth_get_settings_phyless(struct net_device *dev, struct ethto
 static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
-       int err;
 
        /*
         * The MAC does not support 1000baseT_Half.
         */
        cmd->advertising &= ~ADVERTISED_1000baseT_Half;
 
-       spin_lock_irq(&mp->lock);
-       err = mii_ethtool_sset(&mp->mii, cmd);
-       spin_unlock_irq(&mp->lock);
-
-       return err;
+       return phy_ethtool_sset(mp->phy, cmd);
 }
 
 static int mv643xx_eth_set_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -1239,7 +1349,7 @@ static int mv643xx_eth_nway_reset(struct net_device *dev)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
 
-       return mii_nway_restart(&mp->mii);
+       return genphy_restart_aneg(mp->phy);
 }
 
 static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)
@@ -1249,14 +1359,7 @@ static int mv643xx_eth_nway_reset_phyless(struct net_device *dev)
 
 static u32 mv643xx_eth_get_link(struct net_device *dev)
 {
-       struct mv643xx_eth_private *mp = netdev_priv(dev);
-
-       return mii_link_ok(&mp->mii);
-}
-
-static u32 mv643xx_eth_get_link_phyless(struct net_device *dev)
-{
-       return 1;
+       return !!netif_carrier_ok(dev);
 }
 
 static void mv643xx_eth_get_strings(struct net_device *dev,
@@ -1277,9 +1380,10 @@ static void mv643xx_eth_get_ethtool_stats(struct net_device *dev,
                                          struct ethtool_stats *stats,
                                          uint64_t *data)
 {
-       struct mv643xx_eth_private *mp = dev->priv;
+       struct mv643xx_eth_private *mp = netdev_priv(dev);
        int i;
 
+       mv643xx_eth_get_stats(dev);
        mib_counters_update(mp);
 
        for (i = 0; i < ARRAY_SIZE(mv643xx_eth_stats); i++) {
@@ -1323,7 +1427,7 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops_phyless = {
        .set_settings           = mv643xx_eth_set_settings_phyless,
        .get_drvinfo            = mv643xx_eth_get_drvinfo,
        .nway_reset             = mv643xx_eth_nway_reset_phyless,
-       .get_link               = mv643xx_eth_get_link_phyless,
+       .get_link               = mv643xx_eth_get_link,
        .set_sg                 = ethtool_op_set_sg,
        .get_strings            = mv643xx_eth_get_strings,
        .get_ethtool_stats      = mv643xx_eth_get_ethtool_stats,
@@ -1487,7 +1591,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index)
 
        size = rxq->rx_ring_size * sizeof(struct rx_desc);
 
-       if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size) {
+       if (index == 0 && size <= mp->rx_desc_sram_size) {
                rxq->rx_desc_area = ioremap(mp->rx_desc_sram_addr,
                                                mp->rx_desc_sram_size);
                rxq->rx_desc_dma = mp->rx_desc_sram_addr;
@@ -1515,20 +1619,21 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index)
 
        rx_desc = (struct rx_desc *)rxq->rx_desc_area;
        for (i = 0; i < rxq->rx_ring_size; i++) {
-               int nexti = (i + 1) % rxq->rx_ring_size;
+               int nexti;
+
+               nexti = i + 1;
+               if (nexti == rxq->rx_ring_size)
+                       nexti = 0;
+
                rx_desc[i].next_desc_ptr = rxq->rx_desc_dma +
                                        nexti * sizeof(struct rx_desc);
        }
 
-       init_timer(&rxq->rx_oom);
-       rxq->rx_oom.data = (unsigned long)rxq;
-       rxq->rx_oom.function = rxq_refill_timer_wrapper;
-
        return 0;
 
 
 out_free:
-       if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size)
+       if (index == 0 && size <= mp->rx_desc_sram_size)
                iounmap(rxq->rx_desc_area);
        else
                dma_free_coherent(NULL, size,
@@ -1546,8 +1651,6 @@ static void rxq_deinit(struct rx_queue *rxq)
 
        rxq_disable(rxq);
 
-       del_timer_sync(&rxq->rx_oom);
-
        for (i = 0; i < rxq->rx_ring_size; i++) {
                if (rxq->rx_skb[i]) {
                        dev_kfree_skb(rxq->rx_skb[i]);
@@ -1561,7 +1664,7 @@ static void rxq_deinit(struct rx_queue *rxq)
                           rxq->rx_desc_count);
        }
 
-       if (rxq->index == mp->rxq_primary &&
+       if (rxq->index == 0 &&
            rxq->rx_desc_area_size <= mp->rx_desc_sram_size)
                iounmap(rxq->rx_desc_area);
        else
@@ -1588,7 +1691,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
 
        size = txq->tx_ring_size * sizeof(struct tx_desc);
 
-       if (index == mp->txq_primary && size <= mp->tx_desc_sram_size) {
+       if (index == 0 && size <= mp->tx_desc_sram_size) {
                txq->tx_desc_area = ioremap(mp->tx_desc_sram_addr,
                                                mp->tx_desc_sram_size);
                txq->tx_desc_dma = mp->tx_desc_sram_addr;
@@ -1601,120 +1704,97 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
        if (txq->tx_desc_area == NULL) {
                dev_printk(KERN_ERR, &mp->dev->dev,
                           "can't allocate tx ring (%d bytes)\n", size);
-               goto out;
+               return -ENOMEM;
        }
        memset(txq->tx_desc_area, 0, size);
 
        txq->tx_desc_area_size = size;
-       txq->tx_skb = kmalloc(txq->tx_ring_size * sizeof(*txq->tx_skb),
-                                                               GFP_KERNEL);
-       if (txq->tx_skb == NULL) {
-               dev_printk(KERN_ERR, &mp->dev->dev,
-                          "can't allocate tx skb ring\n");
-               goto out_free;
-       }
 
        tx_desc = (struct tx_desc *)txq->tx_desc_area;
        for (i = 0; i < txq->tx_ring_size; i++) {
                struct tx_desc *txd = tx_desc + i;
-               int nexti = (i + 1) % txq->tx_ring_size;
+               int nexti;
+
+               nexti = i + 1;
+               if (nexti == txq->tx_ring_size)
+                       nexti = 0;
 
                txd->cmd_sts = 0;
                txd->next_desc_ptr = txq->tx_desc_dma +
                                        nexti * sizeof(struct tx_desc);
        }
 
-       return 0;
-
-
-out_free:
-       if (index == mp->txq_primary && size <= mp->tx_desc_sram_size)
-               iounmap(txq->tx_desc_area);
-       else
-               dma_free_coherent(NULL, size,
-                                 txq->tx_desc_area,
-                                 txq->tx_desc_dma);
+       skb_queue_head_init(&txq->tx_skb);
 
-out:
-       return -ENOMEM;
+       return 0;
 }
 
-static void txq_reclaim(struct tx_queue *txq, int force)
+static void txq_deinit(struct tx_queue *txq)
 {
        struct mv643xx_eth_private *mp = txq_to_mp(txq);
-       unsigned long flags;
 
-       spin_lock_irqsave(&mp->lock, flags);
-       while (txq->tx_desc_count > 0) {
-               int tx_index;
-               struct tx_desc *desc;
-               u32 cmd_sts;
-               struct sk_buff *skb;
-               dma_addr_t addr;
-               int count;
-
-               tx_index = txq->tx_used_desc;
-               desc = &txq->tx_desc_area[tx_index];
-               cmd_sts = desc->cmd_sts;
+       txq_disable(txq);
+       txq_reclaim(txq, txq->tx_ring_size, 1);
 
-               if (cmd_sts & BUFFER_OWNED_BY_DMA) {
-                       if (!force)
-                               break;
-                       desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA;
-               }
+       BUG_ON(txq->tx_used_desc != txq->tx_curr_desc);
 
-               txq->tx_used_desc = (tx_index + 1) % txq->tx_ring_size;
-               txq->tx_desc_count--;
+       if (txq->index == 0 &&
+           txq->tx_desc_area_size <= mp->tx_desc_sram_size)
+               iounmap(txq->tx_desc_area);
+       else
+               dma_free_coherent(NULL, txq->tx_desc_area_size,
+                                 txq->tx_desc_area, txq->tx_desc_dma);
+}
 
-               addr = desc->buf_ptr;
-               count = desc->byte_cnt;
-               skb = txq->tx_skb[tx_index];
-               txq->tx_skb[tx_index] = NULL;
 
-               if (cmd_sts & ERROR_SUMMARY) {
-                       dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n");
-                       mp->dev->stats.tx_errors++;
-               }
+/* netdev ops and related ***************************************************/
+static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp)
+{
+       u32 int_cause;
+       u32 int_cause_ext;
 
-               /*
-                * Drop mp->lock while we free the skb.
-                */
-               spin_unlock_irqrestore(&mp->lock, flags);
+       int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &
+                       (INT_TX_END | INT_RX | INT_EXT);
+       if (int_cause == 0)
+               return 0;
 
-               if (cmd_sts & TX_FIRST_DESC)
-                       dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
-               else
-                       dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE);
+       int_cause_ext = 0;
+       if (int_cause & INT_EXT)
+               int_cause_ext = rdl(mp, INT_CAUSE_EXT(mp->port_num));
 
-               if (skb)
-                       dev_kfree_skb_irq(skb);
+       int_cause &= INT_TX_END | INT_RX;
+       if (int_cause) {
+               wrl(mp, INT_CAUSE(mp->port_num), ~int_cause);
+               mp->work_tx_end |= ((int_cause & INT_TX_END) >> 19) &
+                               ~(rdl(mp, TXQ_COMMAND(mp->port_num)) & 0xff);
+               mp->work_rx |= (int_cause & INT_RX) >> 2;
+       }
 
-               spin_lock_irqsave(&mp->lock, flags);
+       int_cause_ext &= INT_EXT_LINK_PHY | INT_EXT_TX;
+       if (int_cause_ext) {
+               wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);
+               if (int_cause_ext & INT_EXT_LINK_PHY)
+                       mp->work_link = 1;
+               mp->work_tx |= int_cause_ext & INT_EXT_TX;
        }
-       spin_unlock_irqrestore(&mp->lock, flags);
+
+       return 1;
 }
 
-static void txq_deinit(struct tx_queue *txq)
+static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 {
-       struct mv643xx_eth_private *mp = txq_to_mp(txq);
-
-       txq_disable(txq);
-       txq_reclaim(txq, 1);
+       struct net_device *dev = (struct net_device *)dev_id;
+       struct mv643xx_eth_private *mp = netdev_priv(dev);
 
-       BUG_ON(txq->tx_used_desc != txq->tx_curr_desc);
+       if (unlikely(!mv643xx_eth_collect_events(mp)))
+               return IRQ_NONE;
 
-       if (txq->index == mp->txq_primary &&
-           txq->tx_desc_area_size <= mp->tx_desc_sram_size)
-               iounmap(txq->tx_desc_area);
-       else
-               dma_free_coherent(NULL, txq->tx_desc_area_size,
-                                 txq->tx_desc_area, txq->tx_desc_dma);
+       wrl(mp, INT_MASK(mp->port_num), 0);
+       napi_schedule(&mp->napi);
 
-       kfree(txq->tx_skb);
+       return IRQ_HANDLED;
 }
 
-
-/* netdev ops and related ***************************************************/
 static void handle_link_event(struct mv643xx_eth_private *mp)
 {
        struct net_device *dev = mp->dev;
@@ -1731,15 +1811,12 @@ static void handle_link_event(struct mv643xx_eth_private *mp)
                        printk(KERN_INFO "%s: link down\n", dev->name);
 
                        netif_carrier_off(dev);
-                       netif_stop_queue(dev);
 
-                       for (i = 0; i < 8; i++) {
+                       for (i = 0; i < mp->txq_count; i++) {
                                struct tx_queue *txq = mp->txq + i;
 
-                               if (mp->txq_mask & (1 << i)) {
-                                       txq_reclaim(txq, 1);
-                                       txq_reset_hw_ptr(txq);
-                               }
+                               txq_reclaim(txq, txq->tx_ring_size, 1);
+                               txq_reset_hw_ptr(txq);
                        }
                }
                return;
@@ -1767,119 +1844,93 @@ static void handle_link_event(struct mv643xx_eth_private *mp)
                         speed, duplex ? "full" : "half",
                         fc ? "en" : "dis");
 
-       if (!netif_carrier_ok(dev)) {
+       if (!netif_carrier_ok(dev))
                netif_carrier_on(dev);
-               netif_wake_queue(dev);
-       }
 }
 
-static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
+static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
 {
-       struct net_device *dev = (struct net_device *)dev_id;
-       struct mv643xx_eth_private *mp = netdev_priv(dev);
-       u32 int_cause;
-       u32 int_cause_ext;
-
-       int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &
-                       (INT_TX_END | INT_RX | INT_EXT);
-       if (int_cause == 0)
-               return IRQ_NONE;
-
-       int_cause_ext = 0;
-       if (int_cause & INT_EXT) {
-               int_cause_ext = rdl(mp, INT_CAUSE_EXT(mp->port_num))
-                               & (INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX);
-               wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);
-       }
-
-       if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK))
-               handle_link_event(mp);
+       struct mv643xx_eth_private *mp;
+       int work_done;
 
-       /*
-        * RxBuffer or RxError set for any of the 8 queues?
-        */
-#ifdef MV643XX_ETH_NAPI
-       if (int_cause & INT_RX) {
-               wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_RX));
-               wrl(mp, INT_MASK(mp->port_num), 0x00000000);
-               rdl(mp, INT_MASK(mp->port_num));
+       mp = container_of(napi, struct mv643xx_eth_private, napi);
 
-               netif_rx_schedule(dev, &mp->napi);
-       }
-#else
-       if (int_cause & INT_RX) {
-               int i;
+       mp->work_rx_refill |= mp->work_rx_oom;
+       mp->work_rx_oom = 0;
 
-               for (i = 7; i >= 0; i--)
-                       if (mp->rxq_mask & (1 << i))
-                               rxq_process(mp->rxq + i, INT_MAX);
-       }
-#endif
+       work_done = 0;
+       while (work_done < budget) {
+               u8 queue_mask;
+               int queue;
+               int work_tbd;
 
-       /*
-        * TxBuffer or TxError set for any of the 8 queues?
-        */
-       if (int_cause_ext & INT_EXT_TX) {
-               int i;
+               if (mp->work_link) {
+                       mp->work_link = 0;
+                       handle_link_event(mp);
+                       continue;
+               }
 
-               for (i = 0; i < 8; i++)
-                       if (mp->txq_mask & (1 << i))
-                               txq_reclaim(mp->txq + i, 0);
+               queue_mask = mp->work_tx | mp->work_tx_end |
+                               mp->work_rx | mp->work_rx_refill;
+               if (!queue_mask) {
+                       if (mv643xx_eth_collect_events(mp))
+                               continue;
+                       break;
+               }
 
-               /*
-                * Enough space again in the primary TX queue for a
-                * full packet?
-                */
-               if (netif_carrier_ok(dev)) {
-                       spin_lock(&mp->lock);
-                       __txq_maybe_wake(mp->txq + mp->txq_primary);
-                       spin_unlock(&mp->lock);
+               queue = fls(queue_mask) - 1;
+               queue_mask = 1 << queue;
+
+               work_tbd = budget - work_done;
+               if (work_tbd > 16)
+                       work_tbd = 16;
+
+               if (mp->work_tx_end & queue_mask) {
+                       txq_kick(mp->txq + queue);
+               } else if (mp->work_tx & queue_mask) {
+                       work_done += txq_reclaim(mp->txq + queue, work_tbd, 0);
+                       txq_maybe_wake(mp->txq + queue);
+               } else if (mp->work_rx & queue_mask) {
+                       work_done += rxq_process(mp->rxq + queue, work_tbd);
+               } else if (mp->work_rx_refill & queue_mask) {
+                       work_done += rxq_refill(mp->rxq + queue, work_tbd);
+               } else {
+                       BUG();
                }
        }
 
-       /*
-        * Any TxEnd interrupts?
-        */
-       if (int_cause & INT_TX_END) {
-               int i;
-
-               wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_TX_END));
-
-               spin_lock(&mp->lock);
-               for (i = 0; i < 8; i++) {
-                       struct tx_queue *txq = mp->txq + i;
-                       u32 hw_desc_ptr;
-                       u32 expected_ptr;
-
-                       if ((int_cause & (INT_TX_END_0 << i)) == 0)
-                               continue;
+       if (work_done < budget) {
+               if (mp->work_rx_oom)
+                       mod_timer(&mp->rx_oom, jiffies + (HZ / 10));
+               napi_complete(napi);
+               wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
+       }
 
-                       hw_desc_ptr =
-                               rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, i));
-                       expected_ptr = (u32)txq->tx_desc_dma +
-                               txq->tx_curr_desc * sizeof(struct tx_desc);
+       return work_done;
+}
 
-                       if (hw_desc_ptr != expected_ptr)
-                               txq_enable(txq);
-               }
-               spin_unlock(&mp->lock);
-       }
+static inline void oom_timer_wrapper(unsigned long data)
+{
+       struct mv643xx_eth_private *mp = (void *)data;
 
-       return IRQ_HANDLED;
+       napi_schedule(&mp->napi);
 }
 
 static void phy_reset(struct mv643xx_eth_private *mp)
 {
-       unsigned int data;
+       int data;
+
+       data = phy_read(mp->phy, MII_BMCR);
+       if (data < 0)
+               return;
 
-       smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
        data |= BMCR_RESET;
-       smi_reg_write(mp, mp->phy_addr, MII_BMCR, data);
+       if (phy_write(mp->phy, MII_BMCR, data) < 0)
+               return;
 
        do {
-               udelay(1);
-               smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
-       } while (data & BMCR_RESET);
+               data = phy_read(mp->phy, MII_BMCR);
+       } while (data >= 0 && data & BMCR_RESET);
 }
 
 static void port_start(struct mv643xx_eth_private *mp)
@@ -1890,7 +1941,7 @@ static void port_start(struct mv643xx_eth_private *mp)
        /*
         * Perform PHY reset, if there is a PHY.
         */
-       if (mp->phy_addr != -1) {
+       if (mp->phy != NULL) {
                struct ethtool_cmd cmd;
 
                mv643xx_eth_get_settings(mp->dev, &cmd);
@@ -1907,7 +1958,7 @@ static void port_start(struct mv643xx_eth_private *mp)
        wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
 
        pscr |= DO_NOT_FORCE_LINK_FAIL;
-       if (mp->phy_addr == -1)
+       if (mp->phy == NULL)
                pscr |= FORCE_LINK_PASS;
        wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
 
@@ -1917,12 +1968,9 @@ static void port_start(struct mv643xx_eth_private *mp)
         * Configure TX path and queues.
         */
        tx_set_rate(mp, 1000000000, 16777216);
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < mp->txq_count; i++) {
                struct tx_queue *txq = mp->txq + i;
 
-               if ((mp->txq_mask & (1 << i)) == 0)
-                       continue;
-
                txq_reset_hw_ptr(txq);
                txq_set_rate(txq, 1000000000, 16777216);
                txq_set_fixed_prio_mode(txq);
@@ -1935,9 +1983,10 @@ static void port_start(struct mv643xx_eth_private *mp)
 
        /*
         * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast
-        * frames to RX queue #0.
+        * frames to RX queue #0, and include the pseudo-header when
+        * calculating receive checksums.
         */
-       wrl(mp, PORT_CONFIG(mp->port_num), 0x00000000);
+       wrl(mp, PORT_CONFIG(mp->port_num), 0x02000000);
 
        /*
         * Treat BPDUs as normal multicasts, and disable partition mode.
@@ -1947,14 +1996,11 @@ static void port_start(struct mv643xx_eth_private *mp)
        /*
         * Enable the receive queues.
         */
-       for (i = 0; i < 8; i++) {
+       for (i = 0; i < mp->rxq_count; i++) {
                struct rx_queue *rxq = mp->rxq + i;
                int off = RXQ_CURRENT_DESC_PTR(mp->port_num, i);
                u32 addr;
 
-               if ((mp->rxq_mask & (1 << i)) == 0)
-                       continue;
-
                addr = (u32)rxq->rx_desc_dma;
                addr += rxq->rx_curr_desc * sizeof(struct rx_desc);
                wrl(mp, off, addr);
@@ -1993,6 +2039,26 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int delay)
        wrl(mp, TX_FIFO_URGENT_THRESHOLD(mp->port_num), (coal & 0x3fff) << 4);
 }
 
+static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
+{
+       int skb_size;
+
+       /*
+        * Reserve 2+14 bytes for an ethernet header (the hardware
+        * automatically prepends 2 bytes of dummy data to each
+        * received packet), 16 bytes for up to four VLAN tags, and
+        * 4 bytes for the trailing FCS -- 36 bytes total.
+        */
+       skb_size = mp->dev->mtu + 36;
+
+       /*
+        * Make sure that the skb size is a multiple of 8 bytes, as
+        * the lower three bits of the receive descriptor's buffer
+        * size field are ignored by the hardware.
+        */
+       mp->skb_size = (skb_size + 7) & ~7;
+}
+
 static int mv643xx_eth_open(struct net_device *dev)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
@@ -2004,8 +2070,7 @@ static int mv643xx_eth_open(struct net_device *dev)
        rdl(mp, INT_CAUSE_EXT(mp->port_num));
 
        err = request_irq(dev->irq, mv643xx_eth_irq,
-                         IRQF_SHARED | IRQF_SAMPLE_RANDOM,
-                         dev->name, dev);
+                         IRQF_SHARED, dev->name, dev);
        if (err) {
                dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n");
                return -EAGAIN;
@@ -2013,58 +2078,53 @@ static int mv643xx_eth_open(struct net_device *dev)
 
        init_mac_tables(mp);
 
-       for (i = 0; i < 8; i++) {
-               if ((mp->rxq_mask & (1 << i)) == 0)
-                       continue;
+       mv643xx_eth_recalc_skb_size(mp);
 
+       napi_enable(&mp->napi);
+
+       skb_queue_head_init(&mp->rx_recycle);
+
+       for (i = 0; i < mp->rxq_count; i++) {
                err = rxq_init(mp, i);
                if (err) {
                        while (--i >= 0)
-                               if (mp->rxq_mask & (1 << i))
-                                       rxq_deinit(mp->rxq + i);
+                               rxq_deinit(mp->rxq + i);
                        goto out;
                }
 
-               rxq_refill(mp->rxq + i);
+               rxq_refill(mp->rxq + i, INT_MAX);
        }
 
-       for (i = 0; i < 8; i++) {
-               if ((mp->txq_mask & (1 << i)) == 0)
-                       continue;
+       if (mp->work_rx_oom) {
+               mp->rx_oom.expires = jiffies + (HZ / 10);
+               add_timer(&mp->rx_oom);
+       }
 
+       for (i = 0; i < mp->txq_count; i++) {
                err = txq_init(mp, i);
                if (err) {
                        while (--i >= 0)
-                               if (mp->txq_mask & (1 << i))
-                                       txq_deinit(mp->txq + i);
+                               txq_deinit(mp->txq + i);
                        goto out_free;
                }
        }
 
-#ifdef MV643XX_ETH_NAPI
-       napi_enable(&mp->napi);
-#endif
-
        netif_carrier_off(dev);
-       netif_stop_queue(dev);
 
        port_start(mp);
 
        set_rx_coal(mp, 0);
        set_tx_coal(mp, 0);
 
-       wrl(mp, INT_MASK_EXT(mp->port_num),
-           INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX);
-
+       wrl(mp, INT_MASK_EXT(mp->port_num), INT_EXT_LINK_PHY | INT_EXT_TX);
        wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT);
 
        return 0;
 
 
 out_free:
-       for (i = 0; i < 8; i++)
-               if (mp->rxq_mask & (1 << i))
-                       rxq_deinit(mp->rxq + i);
+       for (i = 0; i < mp->rxq_count; i++)
+               rxq_deinit(mp->rxq + i);
 out:
        free_irq(dev->irq, dev);
 
@@ -2076,12 +2136,10 @@ static void port_reset(struct mv643xx_eth_private *mp)
        unsigned int data;
        int i;
 
-       for (i = 0; i < 8; i++) {
-               if (mp->rxq_mask & (1 << i))
-                       rxq_disable(mp->rxq + i);
-               if (mp->txq_mask & (1 << i))
-                       txq_disable(mp->txq + i);
-       }
+       for (i = 0; i < mp->rxq_count; i++)
+               rxq_disable(mp->rxq + i);
+       for (i = 0; i < mp->txq_count; i++)
+               txq_disable(mp->txq + i);
 
        while (1) {
                u32 ps = rdl(mp, PORT_STATUS(mp->port_num));
@@ -2107,23 +2165,26 @@ static int mv643xx_eth_stop(struct net_device *dev)
        wrl(mp, INT_MASK(mp->port_num), 0x00000000);
        rdl(mp, INT_MASK(mp->port_num));
 
-#ifdef MV643XX_ETH_NAPI
+       del_timer_sync(&mp->mib_counters_timer);
+
        napi_disable(&mp->napi);
-#endif
+
+       del_timer_sync(&mp->rx_oom);
+
        netif_carrier_off(dev);
-       netif_stop_queue(dev);
 
        free_irq(dev->irq, dev);
 
        port_reset(mp);
+       mv643xx_eth_get_stats(dev);
        mib_counters_update(mp);
 
-       for (i = 0; i < 8; i++) {
-               if (mp->rxq_mask & (1 << i))
-                       rxq_deinit(mp->rxq + i);
-               if (mp->txq_mask & (1 << i))
-                       txq_deinit(mp->txq + i);
-       }
+       skb_queue_purge(&mp->rx_recycle);
+
+       for (i = 0; i < mp->rxq_count; i++)
+               rxq_deinit(mp->rxq + i);
+       for (i = 0; i < mp->txq_count; i++)
+               txq_deinit(mp->txq + i);
 
        return 0;
 }
@@ -2132,8 +2193,8 @@ static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
        struct mv643xx_eth_private *mp = netdev_priv(dev);
 
-       if (mp->phy_addr != -1)
-               return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL);
+       if (mp->phy != NULL)
+               return phy_mii_ioctl(mp->phy, if_mii(ifr), cmd);
 
        return -EOPNOTSUPP;
 }
@@ -2146,6 +2207,7 @@ static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu)
                return -EINVAL;
 
        dev->mtu = new_mtu;
+       mv643xx_eth_recalc_skb_size(mp);
        tx_set_rate(mp, 1000000000, 16777216);
 
        if (!netif_running(dev))
@@ -2173,12 +2235,10 @@ static void tx_timeout_task(struct work_struct *ugly)
 
        mp = container_of(ugly, struct mv643xx_eth_private, tx_timeout_task);
        if (netif_running(mp->dev)) {
-               netif_stop_queue(mp->dev);
-
+               netif_tx_stop_all_queues(mp->dev);
                port_reset(mp);
                port_start(mp);
-
-               __txq_maybe_wake(mp->txq + mp->txq_primary);
+               netif_tx_wake_all_queues(mp->dev);
        }
 }
 
@@ -2205,22 +2265,6 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
 }
 #endif
 
-static int mv643xx_eth_mdio_read(struct net_device *dev, int addr, int reg)
-{
-       struct mv643xx_eth_private *mp = netdev_priv(dev);
-       int val;
-
-       smi_reg_read(mp, addr, reg, &val);
-
-       return val;
-}
-
-static void mv643xx_eth_mdio_write(struct net_device *dev, int addr, int reg, int val)
-{
-       struct mv643xx_eth_private *mp = netdev_priv(dev);
-       smi_reg_write(mp, addr, reg, val);
-}
-
 
 /* platform glue ************************************************************/
 static void
@@ -2272,14 +2316,20 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp)
                msp->extended_rx_coal_limit = 0;
 
        /*
-        * Check whether the TX rate control registers are in the
-        * old or the new place.
+        * Check whether the MAC supports TX rate control, and if
+        * yes, whether its associated registers are in the old or
+        * the new place.
         */
        writel(1, msp->base + TX_BW_MTU_MOVED(0));
-       if (readl(msp->base + TX_BW_MTU_MOVED(0)) & 1)
-               msp->tx_bw_control_moved = 1;
-       else
-               msp->tx_bw_control_moved = 0;
+       if (readl(msp->base + TX_BW_MTU_MOVED(0)) & 1) {
+               msp->tx_bw_control = TX_BW_CONTROL_NEW_LAYOUT;
+       } else {
+               writel(7, msp->base + TX_BW_RATE(0));
+               if (readl(msp->base + TX_BW_RATE(0)) & 7)
+                       msp->tx_bw_control = TX_BW_CONTROL_OLD_LAYOUT;
+               else
+                       msp->tx_bw_control = TX_BW_CONTROL_ABSENT;
+       }
 }
 
 static int mv643xx_eth_shared_probe(struct platform_device *pdev)
@@ -2309,7 +2359,41 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
        if (msp->base == NULL)
                goto out_free;
 
-       spin_lock_init(&msp->phy_lock);
+       /*
+        * Set up and register SMI bus.
+        */
+       if (pd == NULL || pd->shared_smi == NULL) {
+               msp->smi_bus.priv = msp;
+               msp->smi_bus.name = "mv643xx_eth smi";
+               msp->smi_bus.read = smi_bus_read;
+               msp->smi_bus.write = smi_bus_write,
+               snprintf(msp->smi_bus.id, MII_BUS_ID_SIZE, "%d", pdev->id);
+               msp->smi_bus.dev = &pdev->dev;
+               msp->smi_bus.phy_mask = 0xffffffff;
+               if (mdiobus_register(&msp->smi_bus) < 0)
+                       goto out_unmap;
+               msp->smi = msp;
+       } else {
+               msp->smi = platform_get_drvdata(pd->shared_smi);
+       }
+
+       msp->err_interrupt = NO_IRQ;
+       init_waitqueue_head(&msp->smi_busy_wait);
+
+       /*
+        * Check whether the error interrupt is hooked up.
+        */
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (res != NULL) {
+               int err;
+
+               err = request_irq(res->start, mv643xx_eth_err_irq,
+                                 IRQF_SHARED, "mv643xx_eth", msp);
+               if (!err) {
+                       writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK);
+                       msp->err_interrupt = res->start;
+               }
+       }
 
        /*
         * (Re-)program MBUS remapping windows if we are asked to.
@@ -2327,6 +2411,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 
        return 0;
 
+out_unmap:
+       iounmap(msp->base);
 out_free:
        kfree(msp);
 out:
@@ -2336,7 +2422,12 @@ out:
 static int mv643xx_eth_shared_remove(struct platform_device *pdev)
 {
        struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev);
+       struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
 
+       if (pd == NULL || pd->shared_smi == NULL)
+               mdiobus_unregister(&msp->smi_bus);
+       if (msp->err_interrupt != NO_IRQ)
+               free_irq(msp->err_interrupt, msp);
        iounmap(msp->base);
        kfree(msp);
 
@@ -2382,33 +2473,13 @@ static void set_params(struct mv643xx_eth_private *mp,
        else
                uc_addr_get(mp, dev->dev_addr);
 
-       if (pd->phy_addr == -1) {
-               mp->shared_smi = NULL;
-               mp->phy_addr = -1;
-       } else {
-               mp->shared_smi = mp->shared;
-               if (pd->shared_smi != NULL)
-                       mp->shared_smi = platform_get_drvdata(pd->shared_smi);
-
-               if (pd->force_phy_addr || pd->phy_addr) {
-                       mp->phy_addr = pd->phy_addr & 0x3f;
-                       phy_addr_set(mp, mp->phy_addr);
-               } else {
-                       mp->phy_addr = phy_addr_get(mp);
-               }
-       }
-
        mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE;
        if (pd->rx_queue_size)
                mp->default_rx_ring_size = pd->rx_queue_size;
        mp->rx_desc_sram_addr = pd->rx_sram_addr;
        mp->rx_desc_sram_size = pd->rx_sram_size;
 
-       if (pd->rx_queue_mask)
-               mp->rxq_mask = pd->rx_queue_mask;
-       else
-               mp->rxq_mask = 0x01;
-       mp->rxq_primary = fls(mp->rxq_mask) - 1;
+       mp->rxq_count = pd->rx_queue_count ? : 1;
 
        mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE;
        if (pd->tx_queue_size)
@@ -2416,76 +2487,63 @@ static void set_params(struct mv643xx_eth_private *mp,
        mp->tx_desc_sram_addr = pd->tx_sram_addr;
        mp->tx_desc_sram_size = pd->tx_sram_size;
 
-       if (pd->tx_queue_mask)
-               mp->txq_mask = pd->tx_queue_mask;
-       else
-               mp->txq_mask = 0x01;
-       mp->txq_primary = fls(mp->txq_mask) - 1;
+       mp->txq_count = pd->tx_queue_count ? : 1;
 }
 
-static int phy_detect(struct mv643xx_eth_private *mp)
+static struct phy_device *phy_scan(struct mv643xx_eth_private *mp,
+                                  int phy_addr)
 {
-       unsigned int data;
-       unsigned int data2;
+       struct mii_bus *bus = &mp->shared->smi->smi_bus;
+       struct phy_device *phydev;
+       int start;
+       int num;
+       int i;
 
-       smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
-       smi_reg_write(mp, mp->phy_addr, MII_BMCR, data ^ BMCR_ANENABLE);
+       if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) {
+               start = phy_addr_get(mp) & 0x1f;
+               num = 32;
+       } else {
+               start = phy_addr & 0x1f;
+               num = 1;
+       }
 
-       smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data2);
-       if (((data ^ data2) & BMCR_ANENABLE) == 0)
-               return -ENODEV;
+       phydev = NULL;
+       for (i = 0; i < num; i++) {
+               int addr = (start + i) & 0x1f;
 
-       smi_reg_write(mp, mp->phy_addr, MII_BMCR, data);
+               if (bus->phy_map[addr] == NULL)
+                       mdiobus_scan(bus, addr);
 
-       return 0;
+               if (phydev == NULL) {
+                       phydev = bus->phy_map[addr];
+                       if (phydev != NULL)
+                               phy_addr_set(mp, addr);
+               }
+       }
+
+       return phydev;
 }
 
-static int phy_init(struct mv643xx_eth_private *mp,
-                   struct mv643xx_eth_platform_data *pd)
+static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex)
 {
-       struct ethtool_cmd cmd;
-       int err;
+       struct phy_device *phy = mp->phy;
 
-       err = phy_detect(mp);
-       if (err) {
-               dev_printk(KERN_INFO, &mp->dev->dev,
-                          "no PHY detected at addr %d\n", mp->phy_addr);
-               return err;
-       }
        phy_reset(mp);
 
-       mp->mii.phy_id = mp->phy_addr;
-       mp->mii.phy_id_mask = 0x3f;
-       mp->mii.reg_num_mask = 0x1f;
-       mp->mii.dev = mp->dev;
-       mp->mii.mdio_read = mv643xx_eth_mdio_read;
-       mp->mii.mdio_write = mv643xx_eth_mdio_write;
-
-       mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii);
-
-       memset(&cmd, 0, sizeof(cmd));
-
-       cmd.port = PORT_MII;
-       cmd.transceiver = XCVR_INTERNAL;
-       cmd.phy_address = mp->phy_addr;
-       if (pd->speed == 0) {
-               cmd.autoneg = AUTONEG_ENABLE;
-               cmd.speed = SPEED_100;
-               cmd.advertising = ADVERTISED_10baseT_Half  |
-                                 ADVERTISED_10baseT_Full  |
-                                 ADVERTISED_100baseT_Half |
-                                 ADVERTISED_100baseT_Full;
-               if (mp->mii.supports_gmii)
-                       cmd.advertising |= ADVERTISED_1000baseT_Full;
+       phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII);
+
+       if (speed == 0) {
+               phy->autoneg = AUTONEG_ENABLE;
+               phy->speed = 0;
+               phy->duplex = 0;
+               phy->advertising = phy->supported | ADVERTISED_Autoneg;
        } else {
-               cmd.autoneg = AUTONEG_DISABLE;
-               cmd.speed = pd->speed;
-               cmd.duplex = pd->duplex;
+               phy->autoneg = AUTONEG_DISABLE;
+               phy->advertising = 0;
+               phy->speed = speed;
+               phy->duplex = duplex;
        }
-
-       mv643xx_eth_set_settings(mp->dev, &cmd);
-
-       return 0;
+       phy_start_aneg(phy);
 }
 
 static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
@@ -2499,7 +2557,7 @@ static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
        }
 
        pscr = MAX_RX_PACKET_9700BYTE | SERIAL_PORT_CONTROL_RESERVED;
-       if (mp->phy_addr == -1) {
+       if (mp->phy == NULL) {
                pscr |= DISABLE_AUTO_NEG_SPEED_GMII;
                if (speed == SPEED_1000)
                        pscr |= SET_GMII_SPEED_TO_1000;
@@ -2538,7 +2596,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       dev = alloc_etherdev(sizeof(struct mv643xx_eth_private));
+       dev = alloc_etherdev_mq(sizeof(struct mv643xx_eth_private), 8);
        if (!dev)
                return -ENOMEM;
 
@@ -2549,33 +2607,47 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
        mp->port_num = pd->port_number;
 
        mp->dev = dev;
-#ifdef MV643XX_ETH_NAPI
-       netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 64);
-#endif
 
        set_params(mp, pd);
+       dev->real_num_tx_queues = mp->txq_count;
 
-       spin_lock_init(&mp->lock);
-
-       mib_counters_clear(mp);
-       INIT_WORK(&mp->tx_timeout_task, tx_timeout_task);
-
-       if (mp->phy_addr != -1) {
-               err = phy_init(mp, pd);
-               if (err)
-                       goto out;
+       if (pd->phy_addr != MV643XX_ETH_PHY_NONE)
+               mp->phy = phy_scan(mp, pd->phy_addr);
 
+       if (mp->phy != NULL) {
+               phy_init(mp, pd->speed, pd->duplex);
                SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops);
        } else {
                SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);
        }
+
        init_pscr(mp, pd->speed, pd->duplex);
 
 
+       mib_counters_clear(mp);
+
+       init_timer(&mp->mib_counters_timer);
+       mp->mib_counters_timer.data = (unsigned long)mp;
+       mp->mib_counters_timer.function = mib_counters_timer_wrapper;
+       mp->mib_counters_timer.expires = jiffies + 30 * HZ;
+       add_timer(&mp->mib_counters_timer);
+
+       spin_lock_init(&mp->mib_counters_lock);
+
+       INIT_WORK(&mp->tx_timeout_task, tx_timeout_task);
+
+       netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128);
+
+       init_timer(&mp->rx_oom);
+       mp->rx_oom.data = (unsigned long)mp;
+       mp->rx_oom.function = oom_timer_wrapper;
+
+
        res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        BUG_ON(!res);
        dev->irq = res->start;
 
+       dev->get_stats = mv643xx_eth_get_stats;
        dev->hard_start_xmit = mv643xx_eth_xmit;
        dev->open = mv643xx_eth_open;
        dev->stop = mv643xx_eth_stop;
@@ -2590,14 +2662,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
        dev->watchdog_timeo = 2 * HZ;
        dev->base_addr = 0;
 
-#ifdef MV643XX_ETH_CHECKSUM_OFFLOAD_TX
-       /*
-        * Zero copy can only work if we use Discovery II memory. Else, we will
-        * have to map the buffers to ISA memory which is only 16 MB
-        */
        dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
        dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;
-#endif
 
        SET_NETDEV_DEV(dev, &pdev->dev);
 
@@ -2611,16 +2677,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
        dev_printk(KERN_NOTICE, &dev->dev, "port %d with MAC address %s\n",
                   mp->port_num, print_mac(mac, dev->dev_addr));
 
-       if (dev->features & NETIF_F_SG)
-               dev_printk(KERN_NOTICE, &dev->dev, "scatter/gather enabled\n");
-
-       if (dev->features & NETIF_F_IP_CSUM)
-               dev_printk(KERN_NOTICE, &dev->dev, "tx checksum offload\n");
-
-#ifdef MV643XX_ETH_NAPI
-       dev_printk(KERN_NOTICE, &dev->dev, "napi enabled\n");
-#endif
-
        if (mp->tx_desc_sram_size > 0)
                dev_printk(KERN_NOTICE, &dev->dev, "configured with sram\n");
 
@@ -2637,6 +2693,8 @@ static int mv643xx_eth_remove(struct platform_device *pdev)
        struct mv643xx_eth_private *mp = platform_get_drvdata(pdev);
 
        unregister_netdev(mp->dev);
+       if (mp->phy != NULL)
+               phy_detach(mp->phy);
        flush_scheduled_work();
        free_netdev(mp->dev);
 
index d6524db321afe06c76eecce80bc3bee52e68355a..005f2aa750193f1a14aeb6ae2dc59435b36b7596 100644 (file)
@@ -183,7 +183,7 @@ struct myri10ge_slice_state {
        dma_addr_t fw_stats_bus;
        int watchdog_tx_done;
        int watchdog_tx_req;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        int cached_dca_tag;
        int cpu;
        __be32 __iomem *dca_tag;
@@ -215,7 +215,7 @@ struct myri10ge_priv {
        int msi_enabled;
        int msix_enabled;
        struct msix_entry *msix_vectors;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        int dca_enabled;
 #endif
        u32 link_state;
@@ -891,7 +891,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
        struct myri10ge_slice_state *ss;
        int i, status;
        size_t bytes;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        unsigned long dca_tag_off;
 #endif
 
@@ -986,7 +986,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
        }
        put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
 
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0);
        dca_tag_off = cmd.data0;
        for (i = 0; i < mgp->num_slices; i++) {
@@ -1025,7 +1025,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
        return status;
 }
 
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
 static void
 myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag)
 {
@@ -1060,8 +1060,9 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp)
        }
        err = dca_add_requester(&pdev->dev);
        if (err) {
-               dev_err(&pdev->dev,
-                       "dca_add_requester() failed, err=%d\n", err);
+               if (err != -ENODEV)
+                       dev_err(&pdev->dev,
+                               "dca_add_requester() failed, err=%d\n", err);
                return;
        }
        mgp->dca_enabled = 1;
@@ -1457,7 +1458,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget)
        struct net_device *netdev = ss->mgp->dev;
        int work_done;
 
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        if (ss->mgp->dca_enabled)
                myri10ge_update_dca(ss);
 #endif
@@ -1686,8 +1687,8 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
        "tx_boundary", "WC", "irq", "MSI", "MSIX",
        "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs",
        "serial_number", "watchdog_resets",
-#ifdef CONFIG_DCA
-       "dca_capable", "dca_enabled",
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
+       "dca_capable_firmware", "dca_device_present",
 #endif
        "link_changes", "link_up", "dropped_link_overflow",
        "dropped_link_error_or_filtered",
@@ -1765,7 +1766,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
        data[i++] = (unsigned int)mgp->read_write_dma;
        data[i++] = (unsigned int)mgp->serial_number;
        data[i++] = (unsigned int)mgp->watchdog_resets;
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL);
        data[i++] = (unsigned int)(mgp->dca_enabled);
 #endif
@@ -3763,7 +3764,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                dev_err(&pdev->dev, "failed reset\n");
                goto abort_with_slices;
        }
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        myri10ge_setup_dca(mgp);
 #endif
        pci_set_drvdata(pdev, mgp);
@@ -3866,7 +3867,7 @@ static void myri10ge_remove(struct pci_dev *pdev)
        netdev = mgp->dev;
        unregister_netdev(netdev);
 
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        myri10ge_teardown_dca(mgp);
 #endif
        myri10ge_dummy_rdma(mgp, 0);
@@ -3911,7 +3912,7 @@ static struct pci_driver myri10ge_driver = {
 #endif
 };
 
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
 static int
 myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p)
 {
@@ -3943,7 +3944,7 @@ static __init int myri10ge_init_module(void)
                       myri10ge_driver.name, myri10ge_rss_hash);
                myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
        }
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        dca_register_notify(&myri10ge_dca_notifier);
 #endif
 
@@ -3954,7 +3955,7 @@ module_init(myri10ge_init_module);
 
 static __exit void myri10ge_cleanup_module(void)
 {
-#ifdef CONFIG_DCA
+#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE)
        dca_unregister_notify(&myri10ge_dca_notifier);
 #endif
        pci_unregister_driver(&myri10ge_driver);
index 656a260fc956b1cf52912da2b3c8aa108d7154c9..06e682334c7e19ace535c67eb811fa5a020ced47 100644 (file)
@@ -1118,7 +1118,7 @@ static int __devexit myri_sbus_remove(struct of_device *dev)
        struct myri_eth *mp = dev_get_drvdata(&dev->dev);
        struct net_device *net_dev = mp->dev;
 
-       unregister_netdevice(net_dev);
+       unregister_netdev(net_dev);
 
        free_irq(net_dev->irq, net_dev);
 
index fa3ceca4e15c0c07f3d414b8fbeb05eb711129cb..eb681c0d51ba1ef61b7537bd6974a9413eabf66e 100644 (file)
@@ -64,6 +64,25 @@ static const char version2[] =
 
 /* Do we support clones that don't adhere to 14,15 of the SAprom ? */
 #define SUPPORT_NE_BAD_CLONES
+/* 0xbad = bad sig or no reset ack */
+#define BAD 0xbad
+
+#define MAX_NE_CARDS   4       /* Max number of NE cards per module */
+static struct platform_device *pdev_ne[MAX_NE_CARDS];
+static int io[MAX_NE_CARDS];
+static int irq[MAX_NE_CARDS];
+static int bad[MAX_NE_CARDS];
+
+#ifdef MODULE
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(bad, int, NULL, 0);
+MODULE_PARM_DESC(io, "I/O base address(es),required");
+MODULE_PARM_DESC(irq, "IRQ number(s)");
+MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
+MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver");
+MODULE_LICENSE("GPL");
+#endif /* MODULE */
 
 /* Do we perform extra sanity checks on stuff ? */
 /* #define NE_SANITY_CHECK */
@@ -74,6 +93,10 @@ static const char version2[] =
 /* Do we have a non std. amount of memory? (in units of 256 byte pages) */
 /* #define PACKETBUF_MEMSIZE   0x40 */
 
+/* This is set up so that no ISA autoprobe takes place. We can't guarantee
+that the ne2k probe is the last 8390 based probe to take place (as it
+is at boot) and so the probe will get confused by any other 8390 cards.
+ISA device autoprobes on a running machine are not recommended anyway. */
 #if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R))
 /* Do we need a portlist for the ISA auto-probe ? */
 #define NEEDS_PORTLIST
@@ -192,8 +215,13 @@ static int __init do_ne_probe(struct net_device *dev)
 #endif
 
        /* First check any supplied i/o locations. User knows best. <cough> */
-       if (base_addr > 0x1ff)  /* Check a single specified location. */
-               return ne_probe1(dev, base_addr);
+       if (base_addr > 0x1ff) {        /* Check a single specified location. */
+               int ret = ne_probe1(dev, base_addr);
+               if (ret)
+                       printk(KERN_WARNING "ne.c: No NE*000 card found at "
+                               "i/o = %#lx\n", base_addr);
+               return ret;
+       }
        else if (base_addr != 0)        /* Don't probe at all. */
                return -ENXIO;
 
@@ -214,28 +242,6 @@ static int __init do_ne_probe(struct net_device *dev)
        return -ENODEV;
 }
 
-#ifndef MODULE
-struct net_device * __init ne_probe(int unit)
-{
-       struct net_device *dev = alloc_eip_netdev();
-       int err;
-
-       if (!dev)
-               return ERR_PTR(-ENOMEM);
-
-       sprintf(dev->name, "eth%d", unit);
-       netdev_boot_setup_check(dev);
-
-       err = do_ne_probe(dev);
-       if (err)
-               goto out;
-       return dev;
-out:
-       free_netdev(dev);
-       return ERR_PTR(err);
-}
-#endif
-
 static int __init ne_probe_isapnp(struct net_device *dev)
 {
        int i;
@@ -329,7 +335,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
           with an otherwise unused dev->mem_end value of "0xBAD" will
           cause the driver to skip these parts of the probe. */
 
-       bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad));
+       bad_card = ((dev->base_addr != 0) && (dev->mem_end == BAD));
 
        /* Reset card. Who knows what dain-bramaged state it was left in. */
 
@@ -806,46 +812,95 @@ retry:
 static int __init ne_drv_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
+       int err, this_dev = pdev->id;
        struct resource *res;
-       int err, irq;
-
-       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       irq = platform_get_irq(pdev, 0);
-       if (!res || irq < 0)
-               return -ENODEV;
 
        dev = alloc_eip_netdev();
        if (!dev)
                return -ENOMEM;
-       dev->irq = irq;
-       dev->base_addr = res->start;
+
+       /* ne.c doesn't populate resources in platform_device, but
+        * rbtx4927_ne_init and rbtx4938_ne_init do register devices
+        * with resources.
+        */
+       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+       if (res) {
+               dev->base_addr = res->start;
+               dev->irq = platform_get_irq(pdev, 0);
+       } else {
+               if (this_dev < 0 || this_dev >= MAX_NE_CARDS)
+                       return -EINVAL;
+               dev->base_addr = io[this_dev];
+               dev->irq = irq[this_dev];
+               dev->mem_end = bad[this_dev];
+       }
        err = do_ne_probe(dev);
        if (err) {
                free_netdev(dev);
                return err;
        }
        platform_set_drvdata(pdev, dev);
+
+       /* Update with any values found by probing, don't update if
+        * resources were specified.
+        */
+       if (!res) {
+               io[this_dev] = dev->base_addr;
+               irq[this_dev] = dev->irq;
+       }
        return 0;
 }
 
-static int __exit ne_drv_remove(struct platform_device *pdev)
+static int ne_drv_remove(struct platform_device *pdev)
 {
        struct net_device *dev = platform_get_drvdata(pdev);
 
-       unregister_netdev(dev);
-       free_irq(dev->irq, dev);
-       release_region(dev->base_addr, NE_IO_EXTENT);
-       free_netdev(dev);
+       if (dev) {
+               struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+               netif_device_detach(dev);
+               unregister_netdev(dev);
+               if (idev)
+                       pnp_device_detach(idev);
+               /* Careful ne_drv_remove can be called twice, once from
+                * the platform_driver.remove and again when the
+                * platform_device is being removed.
+                */
+               ei_status.priv = 0;
+               free_irq(dev->irq, dev);
+               release_region(dev->base_addr, NE_IO_EXTENT);
+               free_netdev(dev);
+               platform_set_drvdata(pdev, NULL);
+       }
        return 0;
 }
 
+/* Remove unused devices or all if true. */
+static void ne_loop_rm_unreg(int all)
+{
+       int this_dev;
+       struct platform_device *pdev;
+       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+               pdev = pdev_ne[this_dev];
+               /* No network device == unused */
+               if (pdev && (!platform_get_drvdata(pdev) || all)) {
+                       ne_drv_remove(pdev);
+                       platform_device_unregister(pdev);
+                       pdev_ne[this_dev] = NULL;
+               }
+       }
+}
+
 #ifdef CONFIG_PM
 static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state)
 {
        struct net_device *dev = platform_get_drvdata(pdev);
 
-       if (netif_running(dev))
+       if (netif_running(dev)) {
+               struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
                netif_device_detach(dev);
+               if (idev)
+                       pnp_stop_dev(idev);
+       }
        return 0;
 }
 
@@ -854,6 +909,9 @@ static int ne_drv_resume(struct platform_device *pdev)
        struct net_device *dev = platform_get_drvdata(pdev);
 
        if (netif_running(dev)) {
+               struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
+               if (idev)
+                       pnp_start_dev(idev);
                ne_reset_8390(dev);
                NS8390p_init(dev, 1);
                netif_device_attach(dev);
@@ -866,7 +924,7 @@ static int ne_drv_resume(struct platform_device *pdev)
 #endif
 
 static struct platform_driver ne_driver = {
-       .remove         = __exit_p(ne_drv_remove),
+       .remove         = ne_drv_remove,
        .suspend        = ne_drv_suspend,
        .resume         = ne_drv_resume,
        .driver         = {
@@ -875,91 +933,96 @@ static struct platform_driver ne_driver = {
        },
 };
 
-static int __init ne_init(void)
+static void __init ne_add_devices(void)
 {
-       return platform_driver_probe(&ne_driver, ne_drv_probe);
-}
+       int this_dev;
+       struct platform_device *pdev;
 
-static void __exit ne_exit(void)
-{
-       platform_driver_unregister(&ne_driver);
+       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+               if (pdev_ne[this_dev])
+                       continue;
+               pdev = platform_device_register_simple(
+                       DRV_NAME, this_dev, NULL, 0);
+               if (IS_ERR(pdev))
+                       continue;
+               pdev_ne[this_dev] = pdev;
+       }
 }
 
 #ifdef MODULE
-#define MAX_NE_CARDS   4       /* Max number of NE cards per module */
-static struct net_device *dev_ne[MAX_NE_CARDS];
-static int io[MAX_NE_CARDS];
-static int irq[MAX_NE_CARDS];
-static int bad[MAX_NE_CARDS];  /* 0xbad = bad sig or no reset ack */
-
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(bad, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es),required");
-MODULE_PARM_DESC(irq, "IRQ number(s)");
-MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures");
-MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that no ISA autoprobe takes place. We can't guarantee
-that the ne2k probe is the last 8390 based probe to take place (as it
-is at boot) and so the probe will get confused by any other 8390 cards.
-ISA device autoprobes on a running machine are not recommended anyway. */
-
-int __init init_module(void)
+int __init init_module()
 {
-       int this_dev, found = 0;
-       int plat_found = !ne_init();
-
-       for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
-               struct net_device *dev = alloc_eip_netdev();
-               if (!dev)
-                       break;
-               dev->irq = irq[this_dev];
-               dev->mem_end = bad[this_dev];
-               dev->base_addr = io[this_dev];
-               if (do_ne_probe(dev) == 0) {
-                       dev_ne[found++] = dev;
-                       continue;
-               }
-               free_netdev(dev);
-               if (found || plat_found)
-                       break;
-               if (io[this_dev] != 0)
-                       printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
-               else
-                       printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
-               return -ENXIO;
+       int retval;
+       ne_add_devices();
+       retval = platform_driver_probe(&ne_driver, ne_drv_probe);
+       if (retval) {
+               if (io[0] == 0)
+                       printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\""
+                               " value(s) for ISA cards.\n");
+               ne_loop_rm_unreg(1);
+               return retval;
        }
-       if (found || plat_found)
-               return 0;
-       return -ENODEV;
-}
 
-static void cleanup_card(struct net_device *dev)
+       /* Unregister unused platform_devices. */
+       ne_loop_rm_unreg(0);
+       return retval;
+}
+#else /* MODULE */
+static int __init ne_init(void)
 {
-       struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv;
-       if (idev)
-               pnp_device_detach(idev);
-       free_irq(dev->irq, dev);
-       release_region(dev->base_addr, NE_IO_EXTENT);
+       int retval = platform_driver_probe(&ne_driver, ne_drv_probe);
+
+       /* Unregister unused platform_devices. */
+       ne_loop_rm_unreg(0);
+       return retval;
 }
+module_init(ne_init);
 
-void __exit cleanup_module(void)
+struct net_device * __init ne_probe(int unit)
 {
        int this_dev;
+       struct net_device *dev;
+
+       /* Find an empty slot, that is no net_device and zero io port. */
+       this_dev = 0;
+       while ((pdev_ne[this_dev] && platform_get_drvdata(pdev_ne[this_dev])) ||
+               io[this_dev]) {
+               if (++this_dev == MAX_NE_CARDS)
+                       return ERR_PTR(-ENOMEM);
+       }
+
+       /* Get irq, io from kernel command line */
+       dev = alloc_eip_netdev();
+       if (!dev)
+               return ERR_PTR(-ENOMEM);
 
-       ne_exit();
+       sprintf(dev->name, "eth%d", unit);
+       netdev_boot_setup_check(dev);
+
+       io[this_dev] = dev->base_addr;
+       irq[this_dev] = dev->irq;
+       bad[this_dev] = dev->mem_end;
+
+       free_netdev(dev);
+
+       ne_add_devices();
+
+       /* return the first device found */
        for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
-               struct net_device *dev = dev_ne[this_dev];
-               if (dev) {
-                       unregister_netdev(dev);
-                       cleanup_card(dev);
-                       free_netdev(dev);
+               if (pdev_ne[this_dev]) {
+                       dev = platform_get_drvdata(pdev_ne[this_dev]);
+                       if (dev)
+                               return dev;
                }
        }
+
+       return ERR_PTR(-ENODEV);
 }
-#else /* MODULE */
-module_init(ne_init);
-module_exit(ne_exit);
 #endif /* MODULE */
+
+static void __exit ne_exit(void)
+{
+       platform_driver_unregister(&ne_driver);
+       ne_loop_rm_unreg(1);
+}
+module_exit(ne_exit);
index 3f9af759cb90a1e47cbcd94f4a313ec824daaab6..b9bed82e1d214089f5b4e6682a965e11c781d6e5 100644 (file)
@@ -189,7 +189,7 @@ netx_eth_interrupt(int irq, void *dev_id)
 
                if ((status & ISR_CON_HI) || (status & ISR_IND_HI))
                        printk("%s: unexpected status: 0x%08x\n",
-                           __FUNCTION__, status);
+                           __func__, status);
 
                fill_level =
                    readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id)));
index 244ab49c4337354e86dce1a4a97208abf54256ff..f8e601c51da71e011ccd0f141b328d29040f2817 100644 (file)
@@ -742,7 +742,7 @@ extern char netxen_nic_driver_name[];
        } while (0)
 #else
 #define DPRINTK(klevel, fmt, args...)  do { \
-       printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\
+       printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\
                (adapter != NULL && adapter->netdev != NULL) ? \
                adapter->netdev->name : NULL, \
                ## args); } while(0)
index 008fd6618a5f527b39abfa4742c9be8b63c67ed3..6ef3f0d84bcf45e8704aaf21958508086df52ee1 100644 (file)
@@ -77,18 +77,18 @@ static irqreturn_t netxen_msi_intr(int irq, void *data);
 
 /*  PCI Device ID Table  */
 #define ENTRY(device) \
-       {PCI_DEVICE(0x4040, (device)), \
+       {PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \
        .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0}
 
 static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
-       ENTRY(0x0001),
-       ENTRY(0x0002),
-       ENTRY(0x0003),
-       ENTRY(0x0004),
-       ENTRY(0x0005),
-       ENTRY(0x0024),
-       ENTRY(0x0025),
-       ENTRY(0x0100),
+       ENTRY(PCI_DEVICE_ID_NX2031_10GXSR),
+       ENTRY(PCI_DEVICE_ID_NX2031_10GCX4),
+       ENTRY(PCI_DEVICE_ID_NX2031_4GCU),
+       ENTRY(PCI_DEVICE_ID_NX2031_IMEZ),
+       ENTRY(PCI_DEVICE_ID_NX2031_HMEZ),
+       ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT),
+       ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT2),
+       ENTRY(PCI_DEVICE_ID_NX3031),
        {0,}
 };
 
@@ -241,7 +241,7 @@ static void netxen_check_options(struct netxen_adapter *adapter)
        case NETXEN_BRDTYPE_P3_REF_QG:
        case NETXEN_BRDTYPE_P3_4_GB:
        case NETXEN_BRDTYPE_P3_4_GB_MM:
-               adapter->msix_supported = 0;
+               adapter->msix_supported = !!use_msi_x;
                adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
                break;
 
index e4765b713abab5afae02980bf6af52d8da8cb8b0..e3be81eba8a44c9f9a96077558450f9203e8b46c 100644 (file)
@@ -5984,6 +5984,56 @@ static void niu_netif_start(struct niu *np)
        niu_enable_interrupts(np, 1);
 }
 
+static void niu_reset_buffers(struct niu *np)
+{
+       int i, j, k, err;
+
+       if (np->rx_rings) {
+               for (i = 0; i < np->num_rx_rings; i++) {
+                       struct rx_ring_info *rp = &np->rx_rings[i];
+
+                       for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) {
+                               struct page *page;
+
+                               page = rp->rxhash[j];
+                               while (page) {
+                                       struct page *next =
+                                               (struct page *) page->mapping;
+                                       u64 base = page->index;
+                                       base = base >> RBR_DESCR_ADDR_SHIFT;
+                                       rp->rbr[k++] = cpu_to_le32(base);
+                                       page = next;
+                               }
+                       }
+                       for (; k < MAX_RBR_RING_SIZE; k++) {
+                               err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k);
+                               if (unlikely(err))
+                                       break;
+                       }
+
+                       rp->rbr_index = rp->rbr_table_size - 1;
+                       rp->rcr_index = 0;
+                       rp->rbr_pending = 0;
+                       rp->rbr_refill_pending = 0;
+               }
+       }
+       if (np->tx_rings) {
+               for (i = 0; i < np->num_tx_rings; i++) {
+                       struct tx_ring_info *rp = &np->tx_rings[i];
+
+                       for (j = 0; j < MAX_TX_RING_SIZE; j++) {
+                               if (rp->tx_buffs[j].skb)
+                                       (void) release_tx_packet(np, rp, j);
+                       }
+
+                       rp->pending = MAX_TX_RING_SIZE;
+                       rp->prod = 0;
+                       rp->cons = 0;
+                       rp->wrap_bit = 0;
+               }
+       }
+}
+
 static void niu_reset_task(struct work_struct *work)
 {
        struct niu *np = container_of(work, struct niu, reset_task);
@@ -6006,6 +6056,12 @@ static void niu_reset_task(struct work_struct *work)
 
        niu_stop_hw(np);
 
+       spin_unlock_irqrestore(&np->lock, flags);
+
+       niu_reset_buffers(np);
+
+       spin_lock_irqsave(&np->lock, flags);
+
        err = niu_init_hw(np);
        if (!err) {
                np->timer.expires = jiffies + HZ;
index 53451c3b2c0decad78e45fdb604e699d882cd9bf..0a575fef29e64521b727ce231ae0cd7510589795 100644 (file)
@@ -119,7 +119,7 @@ KERN_INFO "  Support available from http://foo.com/bar/baz.html\n";
 
 #ifdef NETDRV_DEBUG
 /* note: prints function name for you */
-#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
 #else
 #  define DPRINTK(fmt, args...)
 #endif
@@ -130,7 +130,7 @@ KERN_INFO "  Support available from http://foo.com/bar/baz.html\n";
 #  define assert(expr) \
         if(!(expr)) {                                  \
         printk( "Assertion failed! %s,%s,%s,line=%d\n",        \
-        #expr,__FILE__,__FUNCTION__,__LINE__);         \
+        #expr,__FILE__,__func__,__LINE__);             \
         }
 #endif
 
index 94e0b7ed76f16ff8c2c2a7f43aaf341c4cace12d..e7508c10887c2199ff766961aa30015074b5431a 100644 (file)
@@ -60,49 +60,14 @@ int mdiobus_register(struct mii_bus *bus)
                bus->reset(bus);
 
        for (i = 0; i < PHY_MAX_ADDR; i++) {
-               struct phy_device *phydev;
+               bus->phy_map[i] = NULL;
+               if ((bus->phy_mask & (1 << i)) == 0) {
+                       struct phy_device *phydev;
 
-               if (bus->phy_mask & (1 << i)) {
-                       bus->phy_map[i] = NULL;
-                       continue;
+                       phydev = mdiobus_scan(bus, i);
+                       if (IS_ERR(phydev))
+                               err = PTR_ERR(phydev);
                }
-
-               phydev = get_phy_device(bus, i);
-
-               if (IS_ERR(phydev))
-                       return PTR_ERR(phydev);
-
-               /* There's a PHY at this address
-                * We need to set:
-                * 1) IRQ
-                * 2) bus_id
-                * 3) parent
-                * 4) bus
-                * 5) mii_bus
-                * And, we need to register it */
-               if (phydev) {
-                       phydev->irq = bus->irq[i];
-
-                       phydev->dev.parent = bus->dev;
-                       phydev->dev.bus = &mdio_bus_type;
-                       snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, i);
-
-                       phydev->bus = bus;
-
-                       /* Run all of the fixups for this PHY */
-                       phy_scan_fixups(phydev);
-
-                       err = device_register(&phydev->dev);
-
-                       if (err) {
-                               printk(KERN_ERR "phy %d failed to register\n",
-                                               i);
-                               phy_device_free(phydev);
-                               phydev = NULL;
-                       }
-               }
-
-               bus->phy_map[i] = phydev;
        }
 
        pr_info("%s: probed\n", bus->name);
@@ -122,6 +87,48 @@ void mdiobus_unregister(struct mii_bus *bus)
 }
 EXPORT_SYMBOL(mdiobus_unregister);
 
+struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
+{
+       struct phy_device *phydev;
+       int err;
+
+       phydev = get_phy_device(bus, addr);
+       if (IS_ERR(phydev) || phydev == NULL)
+               return phydev;
+
+       /* There's a PHY at this address
+        * We need to set:
+        * 1) IRQ
+        * 2) bus_id
+        * 3) parent
+        * 4) bus
+        * 5) mii_bus
+        * And, we need to register it */
+
+       phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
+
+       phydev->dev.parent = bus->dev;
+       phydev->dev.bus = &mdio_bus_type;
+       snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, addr);
+
+       phydev->bus = bus;
+
+       /* Run all of the fixups for this PHY */
+       phy_scan_fixups(phydev);
+
+       err = device_register(&phydev->dev);
+       if (err) {
+               printk(KERN_ERR "phy %d failed to register\n", addr);
+               phy_device_free(phydev);
+               phydev = NULL;
+       }
+
+       bus->phy_map[addr] = phydev;
+
+       return phydev;
+}
+EXPORT_SYMBOL(mdiobus_scan);
+
 /**
  * mdio_bus_match - determine if given PHY driver supports the given PHY device
  * @dev: target PHY device
index ddccc074a76a88da15574be350b408e0e9605817..5d4d21516a6c0824224d89f4d814989ad4935227 100644 (file)
@@ -1833,9 +1833,11 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch)
 
        /* If the queue is getting long, don't wait any longer for packets
           before the start of the queue. */
-       if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN
-           && seq_before(ppp->minseq, ppp->mrq.next->sequence))
-               ppp->minseq = ppp->mrq.next->sequence;
+       if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) {
+               struct sk_buff *skb = skb_peek(&ppp->mrq);
+               if (seq_before(ppp->minseq, skb->sequence))
+                       ppp->minseq = skb->sequence;
+       }
 
        /* Pull completed packets off the queue and receive them. */
        while ((skb = ppp_mp_reconstruct(ppp)))
@@ -1864,7 +1866,7 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb)
        for (p = list->next; p != (struct sk_buff *)list; p = p->next)
                if (seq_before(seq, p->sequence))
                        break;
-       __skb_insert(skb, p->prev, p, list);
+       __skb_queue_before(list, p, skb);
 }
 
 /*
index ff175e8f36b274ad58902dc03eb2222cd9c43afa..185b1dff10a8d572494c391aebf515133a56b2ff 100644 (file)
@@ -353,7 +353,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_
        spin_lock_bh(&session->reorder_q.lock);
        skb_queue_walk_safe(&session->reorder_q, skbp, tmp) {
                if (PPPOL2TP_SKB_CB(skbp)->ns > ns) {
-                       __skb_insert(skb, skbp->prev, skbp, &session->reorder_q);
+                       __skb_queue_before(&session->reorder_q, skbp, skb);
                        PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
                               "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n",
                               session->name, ns, PPPOL2TP_SKB_CB(skbp)->ns,
index 5d86281d9363df82406cdadd609dbb019cfd55d3..34fe7ef8e5edf637c1f3c5f301c944e08f598076 100644 (file)
@@ -265,7 +265,7 @@ static void r6040_free_txbufs(struct net_device *dev)
                                le32_to_cpu(lp->tx_insert_ptr->buf),
                                MAX_BUF_SIZE, PCI_DMA_TODEVICE);
                        dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
-                       lp->rx_insert_ptr->skb_ptr = NULL;
+                       lp->tx_insert_ptr->skb_ptr = NULL;
                }
                lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
        }
@@ -370,7 +370,7 @@ static void r6040_init_mac_regs(struct net_device *dev)
        /* Reset internal state machine */
        iowrite16(2, ioaddr + MAC_SM);
        iowrite16(0, ioaddr + MAC_SM);
-       udelay(5000);
+       mdelay(5);
 
        /* MAC Bus Control Register */
        iowrite16(MBCR_DEFAULT, ioaddr + MBCR);
@@ -806,7 +806,7 @@ static void r6040_mac_address(struct net_device *dev)
        iowrite16(0x01, ioaddr + MCR1); /* Reset MAC */
        iowrite16(2, ioaddr + MAC_SM); /* Reset internal state machine */
        iowrite16(0, ioaddr + MAC_SM);
-       udelay(5000);
+       mdelay(5);
 
        /* Restore MAC Address */
        adrp = (u16 *) dev->dev_addr;
index 1822491f19cbcf4b47ad3956c715f25176848c3a..fb899c675f47528403b7f3b50af0acf79bae23a6 100644 (file)
@@ -36,7 +36,7 @@
 #define assert(expr) \
        if (!(expr)) {                                  \
                printk( "Assertion failed! %s,%s,%s,line=%d\n", \
-               #expr,__FILE__,__FUNCTION__,__LINE__);          \
+               #expr,__FILE__,__func__,__LINE__);              \
        }
 #define dprintk(fmt, args...) \
        do { printk(KERN_DEBUG PFX fmt, ## args); } while (0)
@@ -2286,8 +2286,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
 
        RTL_R8(IntrMask);
 
-       RTL_W32(RxMissed, 0);
-
        rtl_set_rx_mode(dev);
 
        RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -2412,8 +2410,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
 
        RTL_R8(IntrMask);
 
-       RTL_W32(RxMissed, 0);
-
        rtl_set_rx_mode(dev);
 
        RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -3191,6 +3187,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
        return work_done;
 }
 
+static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
+{
+       struct rtl8169_private *tp = netdev_priv(dev);
+
+       if (tp->mac_version > RTL_GIGA_MAC_VER_06)
+               return;
+
+       dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
+       RTL_W32(RxMissed, 0);
+}
+
 static void rtl8169_down(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
@@ -3208,9 +3215,7 @@ core_down:
 
        rtl8169_asic_down(ioaddr);
 
-       /* Update the error counts. */
-       dev->stats.rx_missed_errors += RTL_R32(RxMissed);
-       RTL_W32(RxMissed, 0);
+       rtl8169_rx_missed(dev, ioaddr);
 
        spin_unlock_irq(&tp->lock);
 
@@ -3332,8 +3337,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
 
        if (netif_running(dev)) {
                spin_lock_irqsave(&tp->lock, flags);
-               dev->stats.rx_missed_errors += RTL_R32(RxMissed);
-               RTL_W32(RxMissed, 0);
+               rtl8169_rx_missed(dev, ioaddr);
                spin_unlock_irqrestore(&tp->lock, flags);
        }
 
@@ -3358,8 +3362,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
 
        rtl8169_asic_down(ioaddr);
 
-       dev->stats.rx_missed_errors += RTL_R32(RxMissed);
-       RTL_W32(RxMissed, 0);
+       rtl8169_rx_missed(dev, ioaddr);
 
        spin_unlock_irq(&tp->lock);
 
index 243db33042a820247e4eaecf0e03529f9e6f3ac8..6a1375f9cbb81e2c627f2fe1f6606839b9c0c16c 100644 (file)
@@ -371,9 +371,6 @@ static void s2io_vlan_rx_register(struct net_device *dev,
                                flags[i]);
 }
 
-/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */
-static int vlan_strip_flag;
-
 /* Unregister the vlan */
 static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid)
 {
@@ -2303,7 +2300,7 @@ static int start_nic(struct s2io_nic *nic)
                val64 = readq(&bar0->rx_pa_cfg);
                val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG;
                writeq(val64, &bar0->rx_pa_cfg);
-               vlan_strip_flag = 0;
+               nic->vlan_strip_flag = 0;
        }
 
        /*
@@ -3136,7 +3133,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
                if (skb == NULL) {
                        spin_unlock_irqrestore(&fifo_data->tx_lock, flags);
                        DBG_PRINT(ERR_DBG, "%s: Null skb ",
-                       __FUNCTION__);
+                       __func__);
                        DBG_PRINT(ERR_DBG, "in Tx Free Intr\n");
                        return;
                }
@@ -3496,7 +3493,7 @@ static void s2io_reset(struct s2io_nic * sp)
        unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt;
 
        DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
-                       __FUNCTION__, sp->dev->name);
+                       __func__, sp->dev->name);
 
        /* Back up  the PCI-X CMD reg, dont want to lose MMRBC, OST settings */
        pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd));
@@ -3518,7 +3515,7 @@ static void s2io_reset(struct s2io_nic * sp)
        }
 
        if (check_pci_device_id(val16) == (u16)PCI_ANY_ID) {
-               DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __FUNCTION__);
+               DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __func__);
        }
 
        pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd);
@@ -3768,7 +3765,7 @@ static void restore_xmsi_data(struct s2io_nic *nic)
                val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6));
                writeq(val64, &bar0->xmsi_access);
                if (wait_for_msix_trans(nic, msix_index)) {
-                       DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+                       DBG_PRINT(ERR_DBG, "failed in %s\n", __func__);
                        continue;
                }
        }
@@ -3789,7 +3786,7 @@ static void store_xmsi_data(struct s2io_nic *nic)
                val64 = (s2BIT(15) | vBIT(msix_index, 26, 6));
                writeq(val64, &bar0->xmsi_access);
                if (wait_for_msix_trans(nic, msix_index)) {
-                       DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+                       DBG_PRINT(ERR_DBG, "failed in %s\n", __func__);
                        continue;
                }
                addr = readq(&bar0->xmsi_address);
@@ -3812,7 +3809,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
                               GFP_KERNEL);
        if (!nic->entries) {
                DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \
-                       __FUNCTION__);
+                       __func__);
                nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
                return -ENOMEM;
        }
@@ -3826,7 +3823,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
                                   GFP_KERNEL);
        if (!nic->s2io_entries) {
                DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n",
-                       __FUNCTION__);
+                       __func__);
                nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
                kfree(nic->entries);
                nic->mac_control.stats_info->sw_stat.mem_freed
@@ -5010,7 +5007,7 @@ static void s2io_set_multicast(struct net_device *dev)
                        val64 = readq(&bar0->rx_pa_cfg);
                        val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG;
                        writeq(val64, &bar0->rx_pa_cfg);
-                       vlan_strip_flag = 0;
+                       sp->vlan_strip_flag = 0;
                }
 
                val64 = readq(&bar0->mac_cfg);
@@ -5032,7 +5029,7 @@ static void s2io_set_multicast(struct net_device *dev)
                        val64 = readq(&bar0->rx_pa_cfg);
                        val64 |= RX_PA_CFG_STRIP_VLAN_TAG;
                        writeq(val64, &bar0->rx_pa_cfg);
-                       vlan_strip_flag = 1;
+                       sp->vlan_strip_flag = 1;
                }
 
                val64 = readq(&bar0->mac_cfg);
@@ -6746,7 +6743,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu)
                ret = s2io_card_up(sp);
                if (ret) {
                        DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
-                                 __FUNCTION__);
+                                 __func__);
                        return ret;
                }
                s2io_wake_all_tx_queue(sp);
@@ -7530,7 +7527,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
                                        default:
                                                DBG_PRINT(ERR_DBG,
                                                        "%s: Samadhana!!\n",
-                                                        __FUNCTION__);
+                                                        __func__);
                                                BUG();
                                }
                        }
@@ -7781,7 +7778,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
                return -ENOMEM;
        }
        if ((ret = pci_request_regions(pdev, s2io_driver_name))) {
-               DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret);
+               DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __func__, ret);
                pci_disable_device(pdev);
                return -ENODEV;
        }
@@ -7998,7 +7995,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        if (sp->device_type & XFRAME_II_DEVICE) {
                mode = s2io_verify_pci_mode(sp);
                if (mode < 0) {
-                       DBG_PRINT(ERR_DBG, "%s: ", __FUNCTION__);
+                       DBG_PRINT(ERR_DBG, "%s: ", __func__);
                        DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n");
                        ret = -EBADSLT;
                        goto set_swap_failed;
@@ -8206,6 +8203,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        /* Initialize device name */
        sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name);
 
+       if (vlan_tag_strip)
+               sp->vlan_strip_flag = 1;
+       else
+               sp->vlan_strip_flag = 0;
+
        /*
         * Make Link state as off at this point, when the Link change
         * interrupt comes the state will be automatically changed to
@@ -8299,7 +8301,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
 
        if (!(rxdp->Control_1 & RXD_FRAME_PROTO_TCP)) {
                DBG_PRINT(INIT_DBG,"%s: Non-TCP frames not supported for LRO\n",
-                         __FUNCTION__);
+                         __func__);
                return -1;
        }
 
@@ -8311,7 +8313,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
                 * If vlan stripping is disabled and the frame is VLAN tagged,
                 * shift the offset by the VLAN header size bytes.
                 */
-               if ((!vlan_strip_flag) &&
+               if ((!sp->vlan_strip_flag) &&
                        (rxdp->Control_1 & RXD_FRAME_VLAN_TAG))
                        ip_off += HEADER_VLAN_SIZE;
        } else {
@@ -8330,7 +8332,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip,
 static int check_for_socket_match(struct lro *lro, struct iphdr *ip,
                                  struct tcphdr *tcp)
 {
-       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
        if ((lro->iph->saddr != ip->saddr) || (lro->iph->daddr != ip->daddr) ||
           (lro->tcph->source != tcp->source) || (lro->tcph->dest != tcp->dest))
                return -1;
@@ -8345,7 +8347,7 @@ static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp)
 static void initiate_new_session(struct lro *lro, u8 *l2h,
        struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len, u16 vlan_tag)
 {
-       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
        lro->l2h = l2h;
        lro->iph = ip;
        lro->tcph = tcp;
@@ -8375,7 +8377,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
        struct tcphdr *tcp = lro->tcph;
        __sum16 nchk;
        struct stat_block *statinfo = sp->mac_control.stats_info;
-       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
 
        /* Update L3 header */
        ip->tot_len = htons(lro->total_len);
@@ -8403,7 +8405,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro)
 static void aggregate_new_rx(struct lro *lro, struct iphdr *ip,
                struct tcphdr *tcp, u32 l4_pyld)
 {
-       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
        lro->total_len += l4_pyld;
        lro->frags_len += l4_pyld;
        lro->tcp_next_seq += l4_pyld;
@@ -8427,7 +8429,7 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip,
 {
        u8 *ptr;
 
-       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__);
+       DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__);
 
        if (!tcp_pyld_len) {
                /* Runt frame or a pure ack */
@@ -8509,7 +8511,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
 
                        if ((*lro)->tcp_next_seq != ntohl(tcph->seq)) {
                                DBG_PRINT(INFO_DBG, "%s:Out of order. expected "
-                                         "0x%x, actual 0x%x\n", __FUNCTION__,
+                                         "0x%x, actual 0x%x\n", __func__,
                                          (*lro)->tcp_next_seq,
                                          ntohl(tcph->seq));
 
@@ -8549,7 +8551,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
 
        if (ret == 0) { /* sessions exceeded */
                DBG_PRINT(INFO_DBG,"%s:All LRO sessions already in use\n",
-                         __FUNCTION__);
+                         __func__);
                *lro = NULL;
                return ret;
        }
@@ -8571,7 +8573,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp,
                        break;
                default:
                        DBG_PRINT(ERR_DBG,"%s:Dont know, can't say!!\n",
-                               __FUNCTION__);
+                               __func__);
                        break;
        }
 
@@ -8592,7 +8594,7 @@ static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag)
 
        skb->protocol = eth_type_trans(skb, dev);
        if (sp->vlgrp && vlan_tag
-               && (vlan_strip_flag)) {
+               && (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);
index 6722a2f7d0912c93b0b338b0536439521362ef22..55cb943f23f86c8f35a77bd58cae27727dc0dd8e 100644 (file)
@@ -962,6 +962,7 @@ 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;
        struct msix_entry *entries;
index fe41e4ec21ec2141d63df1c291ebc1035c50d4b6..ce10cfa1ee5371c48701ca7cf0cd12e5a38e7672 100644 (file)
@@ -2069,9 +2069,10 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance)
 static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct sbmac_softc *sc = netdev_priv(dev);
+       unsigned long flags;
 
        /* lock eth irq */
-       spin_lock_irq (&sc->sbm_lock);
+       spin_lock_irqsave(&sc->sbm_lock, flags);
 
        /*
         * Put the buffer on the transmit ring.  If we
@@ -2081,14 +2082,14 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
        if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) {
                /* XXX save skb that we could not send */
                netif_stop_queue(dev);
-               spin_unlock_irq(&sc->sbm_lock);
+               spin_unlock_irqrestore(&sc->sbm_lock, flags);
 
                return 1;
        }
 
        dev->trans_start = jiffies;
 
-       spin_unlock_irq (&sc->sbm_lock);
+       spin_unlock_irqrestore(&sc->sbm_lock, flags);
 
        return 0;
 }
@@ -2568,14 +2569,15 @@ static void sbmac_mii_poll(struct net_device *dev)
 static void sbmac_tx_timeout (struct net_device *dev)
 {
        struct sbmac_softc *sc = netdev_priv(dev);
+       unsigned long flags;
 
-       spin_lock_irq (&sc->sbm_lock);
+       spin_lock_irqsave(&sc->sbm_lock, flags);
 
 
        dev->trans_start = jiffies;
        dev->stats.tx_errors++;
 
-       spin_unlock_irq (&sc->sbm_lock);
+       spin_unlock_irqrestore(&sc->sbm_lock, flags);
 
        printk (KERN_WARNING "%s: Transmit timed out\n",dev->name);
 }
index 0d47d6ffe68a4fc670119c1c0a047fab0f6cafb3..06ea71c7e34ecb58bd117781eab7c09360381294 100644 (file)
@@ -445,10 +445,17 @@ static void efx_fini_channels(struct efx_nic *efx)
        struct efx_channel *channel;
        struct efx_tx_queue *tx_queue;
        struct efx_rx_queue *rx_queue;
+       int rc;
 
        EFX_ASSERT_RESET_SERIALISED(efx);
        BUG_ON(efx->port_enabled);
 
+       rc = falcon_flush_queues(efx);
+       if (rc)
+               EFX_ERR(efx, "failed to flush queues\n");
+       else
+               EFX_LOG(efx, "successfully flushed all queues\n");
+
        efx_for_each_channel(channel, efx) {
                EFX_LOG(channel->efx, "shut down chan %d\n", channel->channel);
 
@@ -456,13 +463,6 @@ static void efx_fini_channels(struct efx_nic *efx)
                        efx_fini_rx_queue(rx_queue);
                efx_for_each_channel_tx_queue(tx_queue, channel)
                        efx_fini_tx_queue(tx_queue);
-       }
-
-       /* Do the event queues last so that we can handle flush events
-        * for all DMA queues. */
-       efx_for_each_channel(channel, efx) {
-               EFX_LOG(channel->efx, "shut down evq %d\n", channel->channel);
-
                efx_fini_eventq(channel);
        }
 }
@@ -780,7 +780,7 @@ static int efx_init_io(struct efx_nic *efx)
        return 0;
 
  fail4:
-       release_mem_region(efx->membase_phys, efx->type->mem_map_size);
+       pci_release_region(efx->pci_dev, efx->type->mem_bar);
  fail3:
        efx->membase_phys = 0;
  fail2:
@@ -1092,7 +1092,6 @@ static void efx_stop_all(struct efx_nic *efx)
 
        /* Isolate the MAC from the TX and RX engines, so that queue
         * flushes will complete in a timely fashion. */
-       falcon_deconfigure_mac_wrapper(efx);
        falcon_drain_tx_fifo(efx);
 
        /* Stop the kernel transmit interface late, so the watchdog
@@ -1750,7 +1749,6 @@ static struct efx_phy_operations efx_dummy_phy_operations = {
        .check_hw        = efx_port_dummy_op_int,
        .fini            = efx_port_dummy_op_void,
        .clear_interrupt = efx_port_dummy_op_void,
-       .reset_xaui      = efx_port_dummy_op_void,
 };
 
 static struct efx_board efx_dummy_board_info = {
index e0c0b23f94ef9bb34f959c00f99d0e1c155a462c..31ed1f49de008a547e61828174a39331d00c2512 100644 (file)
@@ -108,10 +108,10 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold");
 /* Max number of internal errors. After this resets will not be performed */
 #define FALCON_MAX_INT_ERRORS 4
 
-/* Maximum period that we wait for flush events. If the flush event
- * doesn't arrive in this period of time then we check if the queue
- * was disabled anyway. */
-#define FALCON_FLUSH_TIMEOUT 10 /* 10ms */
+/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times
+ */
+#define FALCON_FLUSH_INTERVAL 10
+#define FALCON_FLUSH_POLL_COUNT 100
 
 /**************************************************************************
  *
@@ -452,6 +452,8 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue)
        efx_oword_t tx_desc_ptr;
        struct efx_nic *efx = tx_queue->efx;
 
+       tx_queue->flushed = false;
+
        /* Pin TX descriptor ring */
        falcon_init_special_buffer(efx, &tx_queue->txd);
 
@@ -492,60 +494,16 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue)
        }
 }
 
-static int falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
+static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue)
 {
        struct efx_nic *efx = tx_queue->efx;
-       struct efx_channel *channel = &efx->channel[0];
        efx_oword_t tx_flush_descq;
-       unsigned int read_ptr, i;
 
        /* Post a flush command */
        EFX_POPULATE_OWORD_2(tx_flush_descq,
                             TX_FLUSH_DESCQ_CMD, 1,
                             TX_FLUSH_DESCQ, tx_queue->queue);
        falcon_write(efx, &tx_flush_descq, TX_FLUSH_DESCQ_REG_KER);
-       msleep(FALCON_FLUSH_TIMEOUT);
-
-       if (EFX_WORKAROUND_7803(efx))
-               return 0;
-
-       /* Look for a flush completed event */
-       read_ptr = channel->eventq_read_ptr;
-       for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
-               efx_qword_t *event = falcon_event(channel, read_ptr);
-               int ev_code, ev_sub_code, ev_queue;
-               if (!falcon_event_present(event))
-                       break;
-
-               ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
-               ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
-               ev_queue = EFX_QWORD_FIELD(*event, DRIVER_EV_TX_DESCQ_ID);
-               if ((ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) &&
-                   (ev_queue == tx_queue->queue)) {
-                       EFX_LOG(efx, "tx queue %d flush command succesful\n",
-                               tx_queue->queue);
-                       return 0;
-               }
-
-               read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
-       }
-
-       if (EFX_WORKAROUND_11557(efx)) {
-               efx_oword_t reg;
-               bool enabled;
-
-               falcon_read_table(efx, &reg, efx->type->txd_ptr_tbl_base,
-                                 tx_queue->queue);
-               enabled = EFX_OWORD_FIELD(reg, TX_DESCQ_EN);
-               if (!enabled) {
-                       EFX_LOG(efx, "tx queue %d disabled without a "
-                               "flush event seen\n", tx_queue->queue);
-                       return 0;
-               }
-       }
-
-       EFX_ERR(efx, "tx queue %d flush command timed out\n", tx_queue->queue);
-       return -ETIMEDOUT;
 }
 
 void falcon_fini_tx(struct efx_tx_queue *tx_queue)
@@ -553,9 +511,8 @@ void falcon_fini_tx(struct efx_tx_queue *tx_queue)
        struct efx_nic *efx = tx_queue->efx;
        efx_oword_t tx_desc_ptr;
 
-       /* Stop the hardware using the queue */
-       if (falcon_flush_tx_queue(tx_queue))
-               EFX_ERR(efx, "failed to flush tx queue %d\n", tx_queue->queue);
+       /* The queue should have been flushed */
+       WARN_ON(!tx_queue->flushed);
 
        /* Remove TX descriptor ring from card */
        EFX_ZERO_OWORD(tx_desc_ptr);
@@ -643,6 +600,8 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue)
                rx_queue->queue, rx_queue->rxd.index,
                rx_queue->rxd.index + rx_queue->rxd.entries - 1);
 
+       rx_queue->flushed = false;
+
        /* Pin RX descriptor ring */
        falcon_init_special_buffer(efx, &rx_queue->rxd);
 
@@ -663,11 +622,9 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue)
                           rx_queue->queue);
 }
 
-static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
+static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
 {
        struct efx_nic *efx = rx_queue->efx;
-       struct efx_channel *channel = &efx->channel[0];
-       unsigned int read_ptr, i;
        efx_oword_t rx_flush_descq;
 
        /* Post a flush command */
@@ -675,76 +632,15 @@ static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue)
                             RX_FLUSH_DESCQ_CMD, 1,
                             RX_FLUSH_DESCQ, rx_queue->queue);
        falcon_write(efx, &rx_flush_descq, RX_FLUSH_DESCQ_REG_KER);
-       msleep(FALCON_FLUSH_TIMEOUT);
-
-       if (EFX_WORKAROUND_7803(efx))
-               return 0;
-
-       /* Look for a flush completed event */
-       read_ptr = channel->eventq_read_ptr;
-       for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
-               efx_qword_t *event = falcon_event(channel, read_ptr);
-               int ev_code, ev_sub_code, ev_queue;
-               bool ev_failed;
-               if (!falcon_event_present(event))
-                       break;
-
-               ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
-               ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
-               ev_queue = EFX_QWORD_FIELD(*event, DRIVER_EV_RX_DESCQ_ID);
-               ev_failed = EFX_QWORD_FIELD(*event, DRIVER_EV_RX_FLUSH_FAIL);
-
-               if ((ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) &&
-                   (ev_queue == rx_queue->queue)) {
-                       if (ev_failed) {
-                               EFX_INFO(efx, "rx queue %d flush command "
-                                        "failed\n", rx_queue->queue);
-                               return -EAGAIN;
-                       } else {
-                               EFX_LOG(efx, "rx queue %d flush command "
-                                       "succesful\n", rx_queue->queue);
-                               return 0;
-                       }
-               }
-
-               read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
-       }
-
-       if (EFX_WORKAROUND_11557(efx)) {
-               efx_oword_t reg;
-               bool enabled;
-
-               falcon_read_table(efx, &reg, efx->type->rxd_ptr_tbl_base,
-                                 rx_queue->queue);
-               enabled = EFX_OWORD_FIELD(reg, RX_DESCQ_EN);
-               if (!enabled) {
-                       EFX_LOG(efx, "rx queue %d disabled without a "
-                               "flush event seen\n", rx_queue->queue);
-                       return 0;
-               }
-       }
-
-       EFX_ERR(efx, "rx queue %d flush command timed out\n", rx_queue->queue);
-       return -ETIMEDOUT;
 }
 
 void falcon_fini_rx(struct efx_rx_queue *rx_queue)
 {
        efx_oword_t rx_desc_ptr;
        struct efx_nic *efx = rx_queue->efx;
-       int i, rc;
 
-       /* Try and flush the rx queue. This may need to be repeated */
-       for (i = 0; i < 5; i++) {
-               rc = falcon_flush_rx_queue(rx_queue);
-               if (rc == -EAGAIN)
-                       continue;
-               break;
-       }
-       if (rc) {
-               EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue);
-               efx_schedule_reset(efx, RESET_TYPE_INVISIBLE);
-       }
+       /* The queue should already have been flushed */
+       WARN_ON(!rx_queue->flushed);
 
        /* Remove RX descriptor ring from card */
        EFX_ZERO_OWORD(rx_desc_ptr);
@@ -1007,7 +903,7 @@ static void falcon_handle_global_event(struct efx_channel *channel,
                is_phy_event = true;
 
        if ((falcon_rev(efx) >= FALCON_REV_B0) &&
-           EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0))
+           EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0))
                is_phy_event = true;
 
        if (is_phy_event) {
@@ -1255,6 +1151,121 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic)
        falcon_generate_event(channel, &test_event);
 }
 
+/**************************************************************************
+ *
+ * Flush handling
+ *
+ **************************************************************************/
+
+
+static void falcon_poll_flush_events(struct efx_nic *efx)
+{
+       struct efx_channel *channel = &efx->channel[0];
+       struct efx_tx_queue *tx_queue;
+       struct efx_rx_queue *rx_queue;
+       unsigned int read_ptr, i;
+
+       read_ptr = channel->eventq_read_ptr;
+       for (i = 0; i < FALCON_EVQ_SIZE; ++i) {
+               efx_qword_t *event = falcon_event(channel, read_ptr);
+               int ev_code, ev_sub_code, ev_queue;
+               bool ev_failed;
+               if (!falcon_event_present(event))
+                       break;
+
+               ev_code = EFX_QWORD_FIELD(*event, EV_CODE);
+               if (ev_code != DRIVER_EV_DECODE)
+                       continue;
+
+               ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE);
+               switch (ev_sub_code) {
+               case TX_DESCQ_FLS_DONE_EV_DECODE:
+                       ev_queue = EFX_QWORD_FIELD(*event,
+                                                  DRIVER_EV_TX_DESCQ_ID);
+                       if (ev_queue < EFX_TX_QUEUE_COUNT) {
+                               tx_queue = efx->tx_queue + ev_queue;
+                               tx_queue->flushed = true;
+                       }
+                       break;
+               case RX_DESCQ_FLS_DONE_EV_DECODE:
+                       ev_queue = EFX_QWORD_FIELD(*event,
+                                                  DRIVER_EV_RX_DESCQ_ID);
+                       ev_failed = EFX_QWORD_FIELD(*event,
+                                                   DRIVER_EV_RX_FLUSH_FAIL);
+                       if (ev_queue < efx->n_rx_queues) {
+                               rx_queue = efx->rx_queue + ev_queue;
+
+                               /* retry the rx flush */
+                               if (ev_failed)
+                                       falcon_flush_rx_queue(rx_queue);
+                               else
+                                       rx_queue->flushed = true;
+                       }
+                       break;
+               }
+
+               read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK;
+       }
+}
+
+/* Handle tx and rx flushes at the same time, since they run in
+ * parallel in the hardware and there's no reason for us to
+ * serialise them */
+int falcon_flush_queues(struct efx_nic *efx)
+{
+       struct efx_rx_queue *rx_queue;
+       struct efx_tx_queue *tx_queue;
+       int i;
+       bool outstanding;
+
+       /* Issue flush requests */
+       efx_for_each_tx_queue(tx_queue, efx) {
+               tx_queue->flushed = false;
+               falcon_flush_tx_queue(tx_queue);
+       }
+       efx_for_each_rx_queue(rx_queue, efx) {
+               rx_queue->flushed = false;
+               falcon_flush_rx_queue(rx_queue);
+       }
+
+       /* Poll the evq looking for flush completions. Since we're not pushing
+        * any more rx or tx descriptors at this point, we're in no danger of
+        * overflowing the evq whilst we wait */
+       for (i = 0; i < FALCON_FLUSH_POLL_COUNT; ++i) {
+               msleep(FALCON_FLUSH_INTERVAL);
+               falcon_poll_flush_events(efx);
+
+               /* Check if every queue has been succesfully flushed */
+               outstanding = false;
+               efx_for_each_tx_queue(tx_queue, efx)
+                       outstanding |= !tx_queue->flushed;
+               efx_for_each_rx_queue(rx_queue, efx)
+                       outstanding |= !rx_queue->flushed;
+               if (!outstanding)
+                       return 0;
+       }
+
+       /* Mark the queues as all flushed. We're going to return failure
+        * leading to a reset, or fake up success anyway. "flushed" now
+        * indicates that we tried to flush. */
+       efx_for_each_tx_queue(tx_queue, efx) {
+               if (!tx_queue->flushed)
+                       EFX_ERR(efx, "tx queue %d flush command timed out\n",
+                               tx_queue->queue);
+               tx_queue->flushed = true;
+       }
+       efx_for_each_rx_queue(rx_queue, efx) {
+               if (!rx_queue->flushed)
+                       EFX_ERR(efx, "rx queue %d flush command timed out\n",
+                               rx_queue->queue);
+               rx_queue->flushed = true;
+       }
+
+       if (EFX_WORKAROUND_7803(efx))
+               return 0;
+
+       return -ETIMEDOUT;
+}
 
 /**************************************************************************
  *
@@ -1363,10 +1374,11 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx)
                        EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg));
        }
 
-       /* Disable DMA bus mastering on both devices */
+       /* Disable both devices */
        pci_disable_device(efx->pci_dev);
        if (FALCON_IS_DUAL_FUNC(efx))
                pci_disable_device(nic_data->pci_dev2);
+       falcon_disable_interrupts(efx);
 
        if (++n_int_errors < FALCON_MAX_INT_ERRORS) {
                EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n");
@@ -1593,7 +1605,7 @@ void falcon_fini_interrupt(struct efx_nic *efx)
  **************************************************************************
  */
 
-#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t)
+#define FALCON_SPI_MAX_LEN ((unsigned) sizeof(efx_oword_t))
 
 /* Wait for SPI command completion */
 static int falcon_spi_wait(struct efx_nic *efx)
@@ -1942,8 +1954,10 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
 
        /* Wait for transfer to complete */
        for (i = 0; i < 400; i++) {
-               if (*(volatile u32 *)dma_done == FALCON_STATS_DONE)
+               if (*(volatile u32 *)dma_done == FALCON_STATS_DONE) {
+                       rmb(); /* Ensure the stats are valid. */
                        return 0;
+               }
                udelay(10);
        }
 
@@ -2758,6 +2772,8 @@ int falcon_probe_nic(struct efx_nic *efx)
 
        /* Allocate storage for hardware specific data */
        nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL);
+       if (!nic_data)
+               return -ENOMEM;
        efx->nic_data = nic_data;
 
        /* Determine number of ports etc. */
index 30d61e48ac6088219c254dc2d1f42bb936438788..be025ba7a6c6215c0ae2a2e8a3d166cc8f73063c 100644 (file)
@@ -86,6 +86,7 @@ extern void falcon_fini_interrupt(struct efx_nic *efx);
 extern int falcon_probe_nic(struct efx_nic *efx);
 extern int falcon_probe_resources(struct efx_nic *efx);
 extern int falcon_init_nic(struct efx_nic *efx);
+extern int falcon_flush_queues(struct efx_nic *efx);
 extern int falcon_reset_hw(struct efx_nic *efx, enum reset_type method);
 extern void falcon_remove_resources(struct efx_nic *efx);
 extern void falcon_remove_nic(struct efx_nic *efx);
index e319fd64d07c315ac284ddd89a8805009f12b378..5d584b0dbb517043c05ce3d7050ffd999932ce2f 100644 (file)
 #define SF_PRST_WIDTH 1
 #define EE_PRST_LBN 8
 #define EE_PRST_WIDTH 1
-/* See pic_mode_t for decoding of this field */
 /* These bit definitions are extrapolated from the list of numerical
  * values for STRAP_PINS.
  */
index 6670cdfc41abb64426855f80657008531800ca5d..c16da3149fa9ddc6d4fde23482a3f91c08147be3 100644 (file)
@@ -13,7 +13,6 @@
 
 #include <linux/io.h>
 #include <linux/spinlock.h>
-#include "net_driver.h"
 
 /**************************************************************************
  *
index 0d9f68ff71e7285d3b0b5b51da7f04c3007fc735..d4012314dd01f1af81c0ca7be57da7d4dc67a639 100644 (file)
@@ -78,79 +78,7 @@ static void falcon_setup_xaui(struct efx_nic *efx)
        falcon_write(efx, &txdrv, XX_TXDRV_CTL_REG);
 }
 
-static void falcon_hold_xaui_in_rst(struct efx_nic *efx)
-{
-       efx_oword_t reg;
-
-       EFX_ZERO_OWORD(reg);
-       EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1);
-       EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
-}
-
-static int _falcon_reset_xaui_a(struct efx_nic *efx)
-{
-       efx_oword_t reg;
-
-       falcon_hold_xaui_in_rst(efx);
-       falcon_read(efx, &reg, XX_PWR_RST_REG);
-
-       /* Follow the RAMBUS XAUI data reset sequencing
-        * Channels A and B first: power down, reset PLL, reset, clear
-        */
-       EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 0);
-       EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 0);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
-
-       EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 0);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
-
-       EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 0);
-       EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 0);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
-
-       /* Channels C and D: power down, reset PLL, reset, clear */
-       EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 0);
-       EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 0);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
-
-       EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 0);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
-
-       EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 0);
-       EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 0);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
-
-       /* Setup XAUI */
-       falcon_setup_xaui(efx);
-       udelay(10);
-
-       /* Take XGXS out of reset */
-       EFX_ZERO_OWORD(reg);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
-
-       return 0;
-}
-
-static int _falcon_reset_xaui_b(struct efx_nic *efx)
+int falcon_reset_xaui(struct efx_nic *efx)
 {
        efx_oword_t reg;
        int count;
@@ -171,20 +99,6 @@ static int _falcon_reset_xaui_b(struct efx_nic *efx)
        return -ETIMEDOUT;
 }
 
-int falcon_reset_xaui(struct efx_nic *efx)
-{
-       int rc;
-
-       if (EFX_WORKAROUND_9388(efx)) {
-               falcon_hold_xaui_in_rst(efx);
-               efx->phy_op->reset_xaui(efx);
-               rc = _falcon_reset_xaui_a(efx);
-       } else {
-               rc = _falcon_reset_xaui_b(efx);
-       }
-       return rc;
-}
-
 static bool falcon_xgmii_status(struct efx_nic *efx)
 {
        efx_oword_t reg;
index 567df00090fbdc465c3541eb7375dae85501fe8a..cdb11fad6050b0b7700ff8ca64ac8f4afcd68579 100644 (file)
@@ -160,6 +160,7 @@ struct efx_tx_buffer {
  * @channel: The associated channel
  * @buffer: The software buffer ring
  * @txd: The hardware descriptor ring
+ * @flushed: Used when handling queue flushing
  * @read_count: Current read pointer.
  *     This is the number of buffers that have been removed from both rings.
  * @stopped: Stopped count.
@@ -192,6 +193,7 @@ struct efx_tx_queue {
        struct efx_nic *nic;
        struct efx_tx_buffer *buffer;
        struct efx_special_buffer txd;
+       bool flushed;
 
        /* Members used mainly on the completion path */
        unsigned int read_count ____cacheline_aligned_in_smp;
@@ -260,6 +262,7 @@ struct efx_rx_buffer {
  *     the remaining space in the allocation.
  * @buf_dma_addr: Page's DMA address.
  * @buf_data: Page's host address.
+ * @flushed: Use when handling queue flushing
  */
 struct efx_rx_queue {
        struct efx_nic *efx;
@@ -285,6 +288,7 @@ struct efx_rx_queue {
        struct page *buf_page;
        dma_addr_t buf_dma_addr;
        char *buf_data;
+       bool flushed;
 };
 
 /**
@@ -470,7 +474,7 @@ enum nic_state {
  * This is the equivalent of NET_IP_ALIGN [which controls the alignment
  * of the skb->head for hardware DMA].
  */
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 #define EFX_PAGE_IP_ALIGN 0
 #else
 #define EFX_PAGE_IP_ALIGN NET_IP_ALIGN
@@ -503,7 +507,6 @@ enum efx_fc_type {
  * @clear_interrupt: Clear down interrupt
  * @blink: Blink LEDs
  * @check_hw: Check hardware
- * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset)
  * @mmds: MMD presence mask
  * @loopbacks: Supported loopback modes mask
  */
@@ -513,7 +516,6 @@ struct efx_phy_operations {
        void (*reconfigure) (struct efx_nic *efx);
        void (*clear_interrupt) (struct efx_nic *efx);
        int (*check_hw) (struct efx_nic *efx);
-       void (*reset_xaui) (struct efx_nic *efx);
        int (*test) (struct efx_nic *efx);
        int mmds;
        unsigned loopbacks;
index b7005da55d5e257e33e0e78ac85009947fd4ea1f..fe4e3fd223307877ce616020f5a7dd672f734b32 100644 (file)
@@ -129,18 +129,6 @@ static int sfe4001_poweron(struct efx_nic *efx)
        unsigned int i, j;
        int rc;
        u8 out;
-       efx_oword_t reg;
-
-       /* Ensure that XGXS and XAUI SerDes are held in reset */
-       EFX_POPULATE_OWORD_7(reg, XX_PWRDNA_EN, 1,
-                            XX_PWRDNB_EN, 1,
-                            XX_RSTPLLAB_EN, 1,
-                            XX_RESETA_EN, 1,
-                            XX_RESETB_EN, 1,
-                            XX_RSTXGXSRX_EN, 1,
-                            XX_RSTXGXSTX_EN, 1);
-       falcon_write(efx, &reg, XX_PWR_RST_REG);
-       udelay(10);
 
        /* Clear any previous over-temperature alert */
        rc = i2c_smbus_read_byte_data(hwmon_client, RSL);
index 8412dbe1e8fb954eda7286d9f2cc21bf25f59127..d507c93d666e1130dc2cd27768f38f2c4b710221 100644 (file)
@@ -146,8 +146,6 @@ static int tenxpress_phy_check(struct efx_nic *efx)
        return 0;
 }
 
-static void tenxpress_reset_xaui(struct efx_nic *efx);
-
 static int tenxpress_init(struct efx_nic *efx)
 {
        int rc, reg;
@@ -216,7 +214,10 @@ static int tenxpress_special_reset(struct efx_nic *efx)
 {
        int rc, reg;
 
-       EFX_TRACE(efx, "%s\n", __func__);
+       /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so
+        * a special software reset can glitch the XGMAC sufficiently for stats
+        * requests to fail. Since we don't ofen special_reset, just lock. */
+       spin_lock(&efx->stats_lock);
 
        /* Initiate reset */
        reg = mdio_clause45_read(efx, efx->mii.phy_id,
@@ -225,20 +226,22 @@ static int tenxpress_special_reset(struct efx_nic *efx)
        mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
                            PMA_PMD_EXT_CTRL_REG, reg);
 
-       msleep(200);
+       mdelay(200);
 
        /* Wait for the blocks to come out of reset */
        rc = mdio_clause45_wait_reset_mmds(efx,
                                           TENXPRESS_REQUIRED_DEVS);
        if (rc < 0)
-               return rc;
+               goto unlock;
 
        /* Try and reconfigure the device */
        rc = tenxpress_init(efx);
        if (rc < 0)
-               return rc;
+               goto unlock;
 
-       return 0;
+unlock:
+       spin_unlock(&efx->stats_lock);
+       return rc;
 }
 
 static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp)
@@ -374,8 +377,7 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx)
        struct tenxpress_phy_data *phy_data = efx->phy_data;
        bool link_ok;
 
-       link_ok = (phy_data->phy_mode == PHY_MODE_NORMAL &&
-                  tenxpress_link_ok(efx, true));
+       link_ok = tenxpress_link_ok(efx, true);
 
        if (link_ok != efx->link_up)
                falcon_xmac_sim_phy_event(efx);
@@ -428,54 +430,6 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
                            PMA_PMD_LED_OVERR_REG, reg);
 }
 
-static void tenxpress_reset_xaui(struct efx_nic *efx)
-{
-       int phy = efx->mii.phy_id;
-       int clk_ctrl, test_select, soft_rst2;
-
-       /* Real work is done on clock_ctrl other resets are thought to be
-        * optional but make the reset more reliable
-        */
-
-       /* Read */
-       clk_ctrl = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
-                                     PCS_CLOCK_CTRL_REG);
-       test_select = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
-                                        PCS_TEST_SELECT_REG);
-       soft_rst2 = mdio_clause45_read(efx, phy, MDIO_MMD_PCS,
-                                      PCS_SOFT_RST2_REG);
-
-       /* Put in reset */
-       test_select &= ~(1 << CLK312_EN_LBN);
-       mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
-                           PCS_TEST_SELECT_REG, test_select);
-
-       soft_rst2 &= ~((1 << XGXS_RST_N_LBN) | (1 << SERDES_RST_N_LBN));
-       mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
-                           PCS_SOFT_RST2_REG, soft_rst2);
-
-       clk_ctrl &= ~(1 << PLL312_RST_N_LBN);
-       mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
-                           PCS_CLOCK_CTRL_REG, clk_ctrl);
-       udelay(10);
-
-       /* Remove reset */
-       clk_ctrl |= (1 << PLL312_RST_N_LBN);
-       mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
-                           PCS_CLOCK_CTRL_REG, clk_ctrl);
-       udelay(10);
-
-       soft_rst2 |= ((1 << XGXS_RST_N_LBN) | (1 << SERDES_RST_N_LBN));
-       mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
-                           PCS_SOFT_RST2_REG, soft_rst2);
-       udelay(10);
-
-       test_select |= (1 << CLK312_EN_LBN);
-       mdio_clause45_write(efx, phy, MDIO_MMD_PCS,
-                           PCS_TEST_SELECT_REG, test_select);
-       udelay(10);
-}
-
 static int tenxpress_phy_test(struct efx_nic *efx)
 {
        /* BIST is automatically run after a special software reset */
@@ -488,7 +442,6 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = {
        .check_hw         = tenxpress_phy_check_hw,
        .fini             = tenxpress_phy_fini,
        .clear_interrupt  = tenxpress_phy_clear_interrupt,
-       .reset_xaui       = tenxpress_reset_xaui,
        .test             = tenxpress_phy_test,
        .mmds             = TENXPRESS_REQUIRED_DEVS,
        .loopbacks        = TENXPRESS_LOOPBACKS,
index cdee7c200d63d07c558682dae7690bf5f4b995cb..da3e9ff339f5e26c36b070042d86ae5810639b99 100644 (file)
@@ -516,7 +516,7 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue)
 /* Number of bytes inserted at the start of a TSO header buffer,
  * similar to NET_IP_ALIGN.
  */
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 #define TSOH_OFFSET    0
 #else
 #define TSOH_OFFSET    NET_IP_ALIGN
index a824f5998c0486be6780312bc8470d17b2f22d5d..fa7b49d69288d3d3fe201f6cbd1aa788cf1e8e4f 100644 (file)
@@ -24,8 +24,6 @@
 #define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS
 /* TX pkt parser problem with <= 16 byte TXes */
 #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS
-/* XGXS and XAUI reset sequencing in SW */
-#define EFX_WORKAROUND_9388 EFX_WORKAROUND_ALWAYS
 /* Low rate CRC errors require XAUI reset */
 #define EFX_WORKAROUND_10750 EFX_WORKAROUND_ALWAYS
 /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor
index f6edecc2e588c321f83fc71bc4fd6601b64b2813..276151df3a703537ba01a315c90e7842d82ce4a8 100644 (file)
@@ -165,7 +165,6 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
        .check_hw        = xfp_phy_check_hw,
        .fini            = xfp_phy_fini,
        .clear_interrupt = xfp_phy_clear_interrupt,
-       .reset_xaui      = efx_port_dummy_op_void,
        .mmds            = XFP_REQUIRED_DEVS,
        .loopbacks       = XFP_LOOPBACKS,
 };
index ea85de918233ab52c0ecb5b666a066d53e5b1dda..79e665e0853deb67180afda15b482e388cdbe809 100644 (file)
@@ -44,17 +44,10 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req,
                                     int set, int local);
 static int port_to_mib(struct s_smc *smc, int p);
 
-#define MOFFSS(e)      ((int)&(((struct fddi_mib *)0)->e))
-#define MOFFSA(e)      ((int) (((struct fddi_mib *)0)->e))
-
-#define MOFFMS(e)      ((int)&(((struct fddi_mib_m *)0)->e))
-#define MOFFMA(e)      ((int) (((struct fddi_mib_m *)0)->e))
-
-#define MOFFAS(e)      ((int)&(((struct fddi_mib_a *)0)->e))
-#define MOFFAA(e)      ((int) (((struct fddi_mib_a *)0)->e))
-
-#define MOFFPS(e)      ((int)&(((struct fddi_mib_p *)0)->e))
-#define MOFFPA(e)      ((int) (((struct fddi_mib_p *)0)->e))
+#define MOFFSS(e)      offsetof(struct fddi_mib, e)
+#define MOFFMS(e)      offsetof(struct fddi_mib_m, e)
+#define MOFFAS(e)      offsetof(struct fddi_mib_a, e)
+#define MOFFPS(e)      offsetof(struct fddi_mib_p, e)
 
 
 #define AC_G   0x01            /* Get */
@@ -87,8 +80,8 @@ static const struct s_p_tab {
        { SMT_P100D,AC_G,       MOFFSS(fddiSMTOpVersionId),     "S"     } ,
        { SMT_P100E,AC_G,       MOFFSS(fddiSMTHiVersionId),     "S"     } ,
        { SMT_P100F,AC_G,       MOFFSS(fddiSMTLoVersionId),     "S"     } ,
-       { SMT_P1010,AC_G,       MOFFSA(fddiSMTManufacturerData), "D" } ,
-       { SMT_P1011,AC_GR,      MOFFSA(fddiSMTUserData),        "D"     } ,
+       { SMT_P1010,AC_G,       MOFFSS(fddiSMTManufacturerData), "D" } ,
+       { SMT_P1011,AC_GR,      MOFFSS(fddiSMTUserData),        "D"     } ,
        { SMT_P1012,AC_G,       MOFFSS(fddiSMTMIBVersionId),    "S"     } ,
 
        /* StationConfigGrp */
@@ -103,7 +96,7 @@ static const struct s_p_tab {
        { SMT_P101D,AC_GR,      MOFFSS(fddiSMTTT_Notify),       "wS"    } ,
        { SMT_P101E,AC_GR,      MOFFSS(fddiSMTStatRptPolicy),   "bB"    } ,
        { SMT_P101F,AC_GR,      MOFFSS(fddiSMTTrace_MaxExpiration),"lL" } ,
-       { SMT_P1020,AC_G,       MOFFSA(fddiSMTPORTIndexes),     "II"    } ,
+       { SMT_P1020,AC_G,       MOFFSS(fddiSMTPORTIndexes),     "II"    } ,
        { SMT_P1021,AC_G,       MOFFSS(fddiSMTMACIndexes),      "I"     } ,
        { SMT_P1022,AC_G,       MOFFSS(fddiSMTBypassPresent),   "F"     } ,
 
@@ -117,8 +110,8 @@ static const struct s_p_tab {
 
        /* MIBOperationGrp */
        { SMT_P1032,AC_GROUP    } ,
-       { SMT_P1033,AC_G,       MOFFSA(fddiSMTTimeStamp),"P"            } ,
-       { SMT_P1034,AC_G,       MOFFSA(fddiSMTTransitionTimeStamp),"P"  } ,
+       { SMT_P1033,AC_G,       MOFFSS(fddiSMTTimeStamp),"P"            } ,
+       { SMT_P1034,AC_G,       MOFFSS(fddiSMTTransitionTimeStamp),"P"  } ,
        /* NOTE : SMT_P1035 is already swapped ! SMT_P_SETCOUNT */
        { SMT_P1035,AC_G,       MOFFSS(fddiSMTSetCount),"4P"            } ,
        { SMT_P1036,AC_G,       MOFFSS(fddiSMTLastSetStationId),"8"     } ,
@@ -129,7 +122,7 @@ static const struct s_p_tab {
         * PRIVATE EXTENSIONS
         * only accessible locally to get/set passwd
         */
-       { SMT_P10F0,AC_GR,      MOFFSA(fddiPRPMFPasswd),        "8"     } ,
+       { SMT_P10F0,AC_GR,      MOFFSS(fddiPRPMFPasswd),        "8"     } ,
        { SMT_P10F1,AC_GR,      MOFFSS(fddiPRPMFStation),       "8"     } ,
 #ifdef ESS
        { SMT_P10F2,AC_GR,      MOFFSS(fddiESSPayload),         "lL"    } ,
@@ -245,7 +238,7 @@ static const struct s_p_tab {
        { SMT_P400E,AC_GR,      MOFFPS(fddiPORTConnectionPolicies),"bB" } ,
        { SMT_P400F,AC_G,       MOFFPS(fddiPORTMacIndicated),   "2"     } ,
        { SMT_P4010,AC_G,       MOFFPS(fddiPORTCurrentPath),    "E"     } ,
-       { SMT_P4011,AC_GR,      MOFFPA(fddiPORTRequestedPaths), "l4"    } ,
+       { SMT_P4011,AC_GR,      MOFFPS(fddiPORTRequestedPaths), "l4"    } ,
        { SMT_P4012,AC_G,       MOFFPS(fddiPORTMACPlacement),   "S"     } ,
        { SMT_P4013,AC_G,       MOFFPS(fddiPORTAvailablePaths), "B"     } ,
        { SMT_P4016,AC_G,       MOFFPS(fddiPORTPMDClass),       "E"     } ,
index c5871624f972cd3c662e1ba81d22a6f61aabb003..02cc064c2c8b8319836a7f443c6f0ff75867fb79 100644 (file)
@@ -183,7 +183,7 @@ static void smc911x_reset(struct net_device *dev)
        unsigned int reg, timeout=0, resets=1;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        /*       Take out of PM setting first */
        if ((SMC_GET_PMT_CTRL(lp) & PMT_CTRL_READY_) == 0) {
@@ -272,7 +272,7 @@ static void smc911x_enable(struct net_device *dev)
        unsigned mask, cfg, cr;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        SMC_SET_MAC_ADDR(lp, dev->dev_addr);
 
@@ -329,7 +329,7 @@ static void smc911x_shutdown(struct net_device *dev)
        unsigned cr;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __func__);
 
        /* Disable IRQ's */
        SMC_SET_INT_EN(lp, 0);
@@ -348,7 +348,7 @@ static inline void smc911x_drop_pkt(struct net_device *dev)
        struct smc911x_local *lp = netdev_priv(dev);
        unsigned int fifo_count, timeout, reg;
 
-       DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __func__);
        fifo_count = SMC_GET_RX_FIFO_INF(lp) & 0xFFFF;
        if (fifo_count <= 4) {
                /* Manually dump the packet data */
@@ -382,7 +382,7 @@ static inline void   smc911x_rcv(struct net_device *dev)
        unsigned char *data;
 
        DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n",
-               dev->name, __FUNCTION__);
+               dev->name, __func__);
        status = SMC_GET_RX_STS_FIFO(lp);
        DBG(SMC_DEBUG_RX, "%s: Rx pkt len %d status 0x%08x \n",
                dev->name, (status & 0x3fff0000) >> 16, status & 0xc000ffff);
@@ -460,7 +460,7 @@ static void smc911x_hardware_send_pkt(struct net_device *dev)
        unsigned char *buf;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __func__);
        BUG_ON(lp->pending_tx_skb == NULL);
 
        skb = lp->pending_tx_skb;
@@ -524,7 +524,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        unsigned long flags;
 
        DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
-               dev->name, __FUNCTION__);
+               dev->name, __func__);
 
        BUG_ON(lp->pending_tx_skb != NULL);
 
@@ -596,7 +596,7 @@ static void smc911x_tx(struct net_device *dev)
        unsigned int tx_status;
 
        DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n",
-               dev->name, __FUNCTION__);
+               dev->name, __func__);
 
        /* Collect the TX status */
        while (((SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TSUSED_) >> 16) != 0) {
@@ -647,7 +647,7 @@ static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg)
        SMC_GET_MII(lp, phyreg, phyaddr, phydata);
 
        DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%02x, phydata=0x%04x\n",
-               __FUNCTION__, phyaddr, phyreg, phydata);
+               __func__, phyaddr, phyreg, phydata);
        return phydata;
 }
 
@@ -661,7 +661,7 @@ static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg,
        struct smc911x_local *lp = netdev_priv(dev);
 
        DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
-               __FUNCTION__, phyaddr, phyreg, phydata);
+               __func__, phyaddr, phyreg, phydata);
 
        SMC_SET_MII(lp, phyreg, phyaddr, phydata);
 }
@@ -676,7 +676,7 @@ static void smc911x_phy_detect(struct net_device *dev)
        int phyaddr;
        unsigned int cfg, id1, id2;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        lp->phy_type = 0;
 
@@ -746,7 +746,7 @@ static int smc911x_phy_fixed(struct net_device *dev)
        int phyaddr = lp->mii.phy_id;
        int bmcr;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        /* Enter Link Disable state */
        SMC_GET_PHY_BMCR(lp, phyaddr, bmcr);
@@ -793,7 +793,7 @@ static int smc911x_phy_reset(struct net_device *dev, int phy)
        unsigned long flags;
        unsigned int reg;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __func__);
 
        spin_lock_irqsave(&lp->lock, flags);
        reg = SMC_GET_PMT_CTRL(lp);
@@ -852,7 +852,7 @@ static void smc911x_phy_check_media(struct net_device *dev, int init)
        int phyaddr = lp->mii.phy_id;
        unsigned int bmcr, cr;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) {
                /* duplex state has changed */
@@ -892,7 +892,7 @@ static void smc911x_phy_configure(struct work_struct *work)
        int status;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __func__);
 
        /*
         * We should not be called if phy_type is zero.
@@ -985,7 +985,7 @@ static void smc911x_phy_interrupt(struct net_device *dev)
        int phyaddr = lp->mii.phy_id;
        int status;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        if (lp->phy_type == 0)
                return;
@@ -1013,7 +1013,7 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
        unsigned int rx_overrun=0, cr, pkts;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        spin_lock_irqsave(&lp->lock, flags);
 
@@ -1174,8 +1174,6 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id)
 
        spin_unlock_irqrestore(&lp->lock, flags);
 
-       DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout);
-
        return IRQ_HANDLED;
 }
 
@@ -1188,7 +1186,7 @@ smc911x_tx_dma_irq(int dma, void *data)
        struct sk_buff *skb = lp->current_tx_skb;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: TX DMA irq handler\n", dev->name);
        /* Clear the DMA interrupt sources */
@@ -1224,7 +1222,7 @@ smc911x_rx_dma_irq(int dma, void *data)
        unsigned long flags;
        unsigned int pkts;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
        DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA irq handler\n", dev->name);
        /* Clear the DMA interrupt sources */
        SMC_DMA_ACK_IRQ(dev, dma);
@@ -1272,7 +1270,7 @@ static void smc911x_timeout(struct net_device *dev)
        int status, mask;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        spin_lock_irqsave(&lp->lock, flags);
        status = SMC_GET_INT(lp);
@@ -1310,7 +1308,7 @@ static void smc911x_set_multicast_list(struct net_device *dev)
        unsigned int mcr, update_multicast = 0;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        spin_lock_irqsave(&lp->lock, flags);
        SMC_GET_MAC_CR(lp, mcr);
@@ -1412,7 +1410,7 @@ smc911x_open(struct net_device *dev)
 {
        struct smc911x_local *lp = netdev_priv(dev);
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        /*
         * Check that the address is valid.  If its not, refuse
@@ -1420,7 +1418,7 @@ smc911x_open(struct net_device *dev)
         * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
         */
        if (!is_valid_ether_addr(dev->dev_addr)) {
-               PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
+               PRINTK("%s: no valid ethernet hw addr\n", __func__);
                return -EINVAL;
        }
 
@@ -1449,7 +1447,7 @@ static int smc911x_close(struct net_device *dev)
 {
        struct smc911x_local *lp = netdev_priv(dev);
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        netif_stop_queue(dev);
        netif_carrier_off(dev);
@@ -1483,7 +1481,7 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd)
        int ret, status;
        unsigned long flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
        cmd->maxtxpkt = 1;
        cmd->maxrxpkt = 1;
 
@@ -1621,7 +1619,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
        for(timeout=10;(e2p_cmd & E2P_CMD_EPC_BUSY_) && timeout; timeout--) {
                if (e2p_cmd & E2P_CMD_EPC_TIMEOUT_) {
                        PRINTK("%s: %s timeout waiting for EEPROM to respond\n",
-                               dev->name, __FUNCTION__);
+                               dev->name, __func__);
                        return -EFAULT;
                }
                mdelay(1);
@@ -1629,7 +1627,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev)
        }
        if (timeout == 0) {
                PRINTK("%s: %s timeout waiting for EEPROM CMD not busy\n",
-                       dev->name, __FUNCTION__);
+                       dev->name, __func__);
                return -ETIMEDOUT;
        }
        return 0;
@@ -1742,7 +1740,7 @@ static int __init smc911x_findirq(struct net_device *dev)
        int timeout = 20;
        unsigned long cookie;
 
-       DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
 
        cookie = probe_irq_on();
 
@@ -1808,7 +1806,7 @@ static int __init smc911x_probe(struct net_device *dev)
        const char *version_string;
        unsigned long irq_flags;
 
-       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__);
 
        /* First, see if the endian word is recognized */
        val = SMC_GET_BYTE_TEST(lp);
@@ -2058,7 +2056,7 @@ static int smc911x_drv_probe(struct platform_device *pdev)
        unsigned int *addr;
        int ret;
 
-       DBG(SMC_DEBUG_FUNC, "--> %s\n",  __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "--> %s\n",  __func__);
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res) {
                ret = -ENODEV;
@@ -2129,7 +2127,7 @@ static int smc911x_drv_remove(struct platform_device *pdev)
        struct smc911x_local *lp = netdev_priv(ndev);
        struct resource *res;
 
-       DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
        platform_set_drvdata(pdev, NULL);
 
        unregister_netdev(ndev);
@@ -2159,7 +2157,7 @@ static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state)
        struct net_device *ndev = platform_get_drvdata(dev);
        struct smc911x_local *lp = netdev_priv(ndev);
 
-       DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
        if (ndev) {
                if (netif_running(ndev)) {
                        netif_device_detach(ndev);
@@ -2177,7 +2175,7 @@ static int smc911x_drv_resume(struct platform_device *dev)
 {
        struct net_device *ndev = platform_get_drvdata(dev);
 
-       DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__);
+       DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__);
        if (ndev) {
                struct smc911x_local *lp = netdev_priv(ndev);
 
index 24768c10cadb7d1e326b3651ce6819ec08021699..ef5ce8845c9d779d7be372ea03539921fca294f5 100644 (file)
@@ -270,7 +270,7 @@ static void smc_reset(struct net_device *dev)
        unsigned int ctl, cfg;
        struct sk_buff *pending_skb;
 
-       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(2, "%s: %s\n", dev->name, __func__);
 
        /* Disable all interrupts, block TX tasklet */
        spin_lock_irq(&lp->lock);
@@ -363,7 +363,7 @@ static void smc_enable(struct net_device *dev)
        void __iomem *ioaddr = lp->base;
        int mask;
 
-       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(2, "%s: %s\n", dev->name, __func__);
 
        /* see the header file for options in TCR/RCR DEFAULT */
        SMC_SELECT_BANK(lp, 0);
@@ -397,7 +397,7 @@ static void smc_shutdown(struct net_device *dev)
        void __iomem *ioaddr = lp->base;
        struct sk_buff *pending_skb;
 
-       DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+       DBG(2, "%s: %s\n", CARDNAME, __func__);
 
        /* no more interrupts for me */
        spin_lock_irq(&lp->lock);
@@ -430,7 +430,7 @@ static inline void  smc_rcv(struct net_device *dev)
        void __iomem *ioaddr = lp->base;
        unsigned int packet_number, status, packet_len;
 
-       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(3, "%s: %s\n", dev->name, __func__);
 
        packet_number = SMC_GET_RXFIFO(lp);
        if (unlikely(packet_number & RXFIFO_REMPTY)) {
@@ -577,7 +577,7 @@ static void smc_hardware_send_pkt(unsigned long data)
        unsigned int packet_no, len;
        unsigned char *buf;
 
-       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(3, "%s: %s\n", dev->name, __func__);
 
        if (!smc_special_trylock(&lp->lock)) {
                netif_stop_queue(dev);
@@ -662,7 +662,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        void __iomem *ioaddr = lp->base;
        unsigned int numPages, poll_count, status;
 
-       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(3, "%s: %s\n", dev->name, __func__);
 
        BUG_ON(lp->pending_tx_skb != NULL);
 
@@ -734,7 +734,7 @@ static void smc_tx(struct net_device *dev)
        void __iomem *ioaddr = lp->base;
        unsigned int saved_packet, packet_no, tx_status, pkt_len;
 
-       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(3, "%s: %s\n", dev->name, __func__);
 
        /* If the TX FIFO is empty then nothing to do */
        packet_no = SMC_GET_TXFIFO(lp);
@@ -856,7 +856,7 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg)
        SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
 
        DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
-               __FUNCTION__, phyaddr, phyreg, phydata);
+               __func__, phyaddr, phyreg, phydata);
 
        SMC_SELECT_BANK(lp, 2);
        return phydata;
@@ -883,7 +883,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg,
        SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO));
 
        DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
-               __FUNCTION__, phyaddr, phyreg, phydata);
+               __func__, phyaddr, phyreg, phydata);
 
        SMC_SELECT_BANK(lp, 2);
 }
@@ -896,7 +896,7 @@ static void smc_phy_detect(struct net_device *dev)
        struct smc_local *lp = netdev_priv(dev);
        int phyaddr;
 
-       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(2, "%s: %s\n", dev->name, __func__);
 
        lp->phy_type = 0;
 
@@ -935,7 +935,7 @@ static int smc_phy_fixed(struct net_device *dev)
        int phyaddr = lp->mii.phy_id;
        int bmcr, cfg1;
 
-       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(3, "%s: %s\n", dev->name, __func__);
 
        /* Enter Link Disable state */
        cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG);
@@ -1168,7 +1168,7 @@ static void smc_phy_interrupt(struct net_device *dev)
        int phyaddr = lp->mii.phy_id;
        int phy18;
 
-       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(2, "%s: %s\n", dev->name, __func__);
 
        if (lp->phy_type == 0)
                return;
@@ -1236,7 +1236,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
        int status, mask, timeout, card_stats;
        int saved_pointer;
 
-       DBG(3, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(3, "%s: %s\n", dev->name, __func__);
 
        spin_lock(&lp->lock);
 
@@ -1358,7 +1358,7 @@ static void smc_timeout(struct net_device *dev)
        void __iomem *ioaddr = lp->base;
        int status, mask, eph_st, meminfo, fifo;
 
-       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(2, "%s: %s\n", dev->name, __func__);
 
        spin_lock_irq(&lp->lock);
        status = SMC_GET_INT(lp);
@@ -1402,7 +1402,7 @@ static void smc_set_multicast_list(struct net_device *dev)
        unsigned char multicast_table[8];
        int update_multicast = 0;
 
-       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(2, "%s: %s\n", dev->name, __func__);
 
        if (dev->flags & IFF_PROMISC) {
                DBG(2, "%s: RCR_PRMS\n", dev->name);
@@ -1505,7 +1505,7 @@ smc_open(struct net_device *dev)
 {
        struct smc_local *lp = netdev_priv(dev);
 
-       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(2, "%s: %s\n", dev->name, __func__);
 
        /*
         * Check that the address is valid.  If its not, refuse
@@ -1513,7 +1513,7 @@ smc_open(struct net_device *dev)
         * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
         */
        if (!is_valid_ether_addr(dev->dev_addr)) {
-               PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__);
+               PRINTK("%s: no valid ethernet hw addr\n", __func__);
                return -EINVAL;
        }
 
@@ -1557,7 +1557,7 @@ static int smc_close(struct net_device *dev)
 {
        struct smc_local *lp = netdev_priv(dev);
 
-       DBG(2, "%s: %s\n", dev->name, __FUNCTION__);
+       DBG(2, "%s: %s\n", dev->name, __func__);
 
        netif_stop_queue(dev);
        netif_carrier_off(dev);
@@ -1700,7 +1700,7 @@ static int __init smc_findirq(struct smc_local *lp)
        int timeout = 20;
        unsigned long cookie;
 
-       DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+       DBG(2, "%s: %s\n", CARDNAME, __func__);
 
        cookie = probe_irq_on();
 
@@ -1778,7 +1778,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
        const char *version_string;
        DECLARE_MAC_BUF(mac);
 
-       DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__);
+       DBG(2, "%s: %s\n", CARDNAME, __func__);
 
        /* First, see if the high byte is 0x33 */
        val = SMC_CURRENT_BANK(lp);
@@ -1961,7 +1961,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr,
                if (dev->dma != (unsigned char)-1)
                        printk(" DMA %d", dev->dma);
 
-               printk("%s%s\n", nowait ? " [nowait]" : "",
+               printk("%s%s\n",
+                       lp->cfg.flags & SMC91X_NOWAIT ? " [nowait]" : "",
                        THROTTLE_TX_PKTS ? " [throttle_tx]" : "");
 
                if (!is_valid_ether_addr(dev->dev_addr)) {
index 997e7f1d5c6e496b42bd602baf473f16acfd45e2..edea0732f1454dc0b5ee30a7e02256400dcc70c2 100644 (file)
@@ -446,6 +446,8 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
 #define SMC_CAN_USE_32BIT      1
 #define SMC_NOWAIT             1
 
+#define SMC_IO_SHIFT           (lp->io_shift)
+
 #define SMC_inb(a, r)          readb((a) + (r))
 #define SMC_inw(a, r)          readw((a) + (r))
 #define SMC_inl(a, r)          readl((a) + (r))
index 0e4a88d16327914a42af9116cdbc8db42443dd27..31e7384e312ad71a437144acb030730e34771d8e 100644 (file)
@@ -1274,7 +1274,7 @@ static int __devexit bigmac_sbus_remove(struct of_device *dev)
        struct bigmac *bp = dev_get_drvdata(&dev->dev);
        struct net_device *net_dev = bp->dev;
 
-       unregister_netdevice(net_dev);
+       unregister_netdev(net_dev);
 
        sbus_iounmap(bp->gregs, GLOB_REG_SIZE);
        sbus_iounmap(bp->creg, CREG_REG_SIZE);
index 7d5561b8241cb3aa730c3902e7b2b05158b3ee13..f860ea150395871357639e4f457834fbf67408c1 100644 (file)
@@ -409,6 +409,7 @@ static int  change_mtu(struct net_device *dev, int new_mtu);
 static int  eeprom_read(void __iomem *ioaddr, int location);
 static int  mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
+static int  mdio_wait_link(struct net_device *dev, int wait);
 static int  netdev_open(struct net_device *dev);
 static void check_duplex(struct net_device *dev);
 static void netdev_timer(unsigned long data);
@@ -785,6 +786,24 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val
        return;
 }
 
+static int mdio_wait_link(struct net_device *dev, int wait)
+{
+       int bmsr;
+       int phy_id;
+       struct netdev_private *np;
+
+       np = netdev_priv(dev);
+       phy_id = np->phys[0];
+
+       do {
+               bmsr = mdio_read(dev, phy_id, MII_BMSR);
+               if (bmsr & 0x0004)
+                       return 0;
+               mdelay(1);
+       } while (--wait > 0);
+       return -1;
+}
+
 static int netdev_open(struct net_device *dev)
 {
        struct netdev_private *np = netdev_priv(dev);
@@ -1393,41 +1412,51 @@ static void netdev_error(struct net_device *dev, int intr_status)
        int speed;
 
        if (intr_status & LinkChange) {
-               if (np->an_enable) {
-                       mii_advertise = mdio_read (dev, np->phys[0], MII_ADVERTISE);
-                       mii_lpa= mdio_read (dev, np->phys[0], MII_LPA);
-                       mii_advertise &= mii_lpa;
-                       printk (KERN_INFO "%s: Link changed: ", dev->name);
-                       if (mii_advertise & ADVERTISE_100FULL) {
-                               np->speed = 100;
-                               printk ("100Mbps, full duplex\n");
-                       } else if (mii_advertise & ADVERTISE_100HALF) {
-                               np->speed = 100;
-                               printk ("100Mbps, half duplex\n");
-                       } else if (mii_advertise & ADVERTISE_10FULL) {
-                               np->speed = 10;
-                               printk ("10Mbps, full duplex\n");
-                       } else if (mii_advertise & ADVERTISE_10HALF) {
-                               np->speed = 10;
-                               printk ("10Mbps, half duplex\n");
-                       } else
-                               printk ("\n");
+               if (mdio_wait_link(dev, 10) == 0) {
+                       printk(KERN_INFO "%s: Link up\n", dev->name);
+                       if (np->an_enable) {
+                               mii_advertise = mdio_read(dev, np->phys[0],
+                                                          MII_ADVERTISE);
+                               mii_lpa = mdio_read(dev, np->phys[0], MII_LPA);
+                               mii_advertise &= mii_lpa;
+                               printk(KERN_INFO "%s: Link changed: ",
+                                       dev->name);
+                               if (mii_advertise & ADVERTISE_100FULL) {
+                                       np->speed = 100;
+                                       printk("100Mbps, full duplex\n");
+                               } else if (mii_advertise & ADVERTISE_100HALF) {
+                                       np->speed = 100;
+                                       printk("100Mbps, half duplex\n");
+                               } else if (mii_advertise & ADVERTISE_10FULL) {
+                                       np->speed = 10;
+                                       printk("10Mbps, full duplex\n");
+                               } else if (mii_advertise & ADVERTISE_10HALF) {
+                                       np->speed = 10;
+                                       printk("10Mbps, half duplex\n");
+                               } else
+                                       printk("\n");
 
+                       } else {
+                               mii_ctl = mdio_read(dev, np->phys[0], MII_BMCR);
+                               speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
+                               np->speed = speed;
+                               printk(KERN_INFO "%s: Link changed: %dMbps ,",
+                                       dev->name, speed);
+                               printk("%s duplex.\n",
+                                       (mii_ctl & BMCR_FULLDPLX) ?
+                                               "full" : "half");
+                       }
+                       check_duplex(dev);
+                       if (np->flowctrl && np->mii_if.full_duplex) {
+                               iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
+                                       ioaddr + MulticastFilter1+2);
+                               iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
+                                       ioaddr + MACCtrl0);
+                       }
+                       netif_carrier_on(dev);
                } else {
-                       mii_ctl = mdio_read (dev, np->phys[0], MII_BMCR);
-                       speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
-                       np->speed = speed;
-                       printk (KERN_INFO "%s: Link changed: %dMbps ,",
-                               dev->name, speed);
-                       printk ("%s duplex.\n", (mii_ctl & BMCR_FULLDPLX) ?
-                               "full" : "half");
-               }
-               check_duplex (dev);
-               if (np->flowctrl && np->mii_if.full_duplex) {
-                       iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200,
-                               ioaddr + MulticastFilter1+2);
-                       iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl,
-                               ioaddr + MACCtrl0);
+                       printk(KERN_INFO "%s: Link down\n", dev->name);
+                       netif_carrier_off(dev);
                }
        }
        if (intr_status & StatsMax) {
index 7db48f1cd9498873be69a70a0cd7fa3ac4aada10..efaf84d9757d139fd88fef5b7311f9f273fc389c 100644 (file)
@@ -539,22 +539,22 @@ struct txd_desc {
 
 #define ERR(fmt, args...) printk(KERN_ERR fmt, ## args)
 #define DBG2(fmt, args...)     \
-       printk(KERN_ERR  "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args)
+       printk(KERN_ERR  "%s:%-5d: " fmt, __func__, __LINE__, ## args)
 
 #define BDX_ASSERT(x) BUG_ON(x)
 
 #ifdef DEBUG
 
 #define ENTER          do { \
-       printk(KERN_ERR  "%s:%-5d: ENTER\n", __FUNCTION__, __LINE__); \
+       printk(KERN_ERR  "%s:%-5d: ENTER\n", __func__, __LINE__); \
 } while (0)
 
 #define RET(args...)   do { \
-       printk(KERN_ERR  "%s:%-5d: RETURN\n", __FUNCTION__, __LINE__); \
+       printk(KERN_ERR  "%s:%-5d: RETURN\n", __func__, __LINE__); \
 return args; } while (0)
 
 #define DBG(fmt, args...)      \
-       printk(KERN_ERR  "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args)
+       printk(KERN_ERR  "%s:%-5d: " fmt, __func__, __LINE__, ## args)
 #else
 #define ENTER         do {  } while (0)
 #define RET(args...)   return args
index 43fde99b24ac0c829d48b03228ddbdf4aa72092a..eb1da6f0b0863cbd827224ddebbc3d5e19275e35 100644 (file)
@@ -263,7 +263,7 @@ static inline void tsi108_write_tbi(struct tsi108_prv_data *data,
                        return;
                udelay(10);
        }
-       printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+       printk(KERN_ERR "%s function time out \n", __func__);
 }
 
 static int mii_speed(struct mii_if_info *mii)
@@ -1059,7 +1059,7 @@ static void tsi108_stop_ethernet(struct net_device *dev)
                        return;
                udelay(10);
        }
-       printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+       printk(KERN_ERR "%s function time out \n", __func__);
 }
 
 static void tsi108_reset_ether(struct tsi108_prv_data * data)
@@ -1244,7 +1244,7 @@ static void tsi108_init_phy(struct net_device *dev)
                udelay(10);
        }
        if (i == 0)
-               printk(KERN_ERR "%s function time out \n", __FUNCTION__);
+               printk(KERN_ERR "%s function time out \n", __func__);
 
        if (data->phy_type == TSI108_PHY_BCM54XX) {
                tsi108_write_mii(data, 0x09, 0x0300);
index 9281d06d5aaab071163b7c53ff14087b8db66436..f54c45049d50d86c700e3f18a5c2525321a662c9 100644 (file)
@@ -1418,7 +1418,6 @@ static int de_close (struct net_device *dev)
 
        de_free_rings(de);
        de_adapter_sleep(de);
-       pci_disable_device(de->pdev);
        return 0;
 }
 
index 617ef41bdfea669b316085ad373802e47a259e8f..6444cbec0bdc8dd02a0a9eca4c2066af15be2a96 100644 (file)
@@ -832,7 +832,7 @@ struct de4x5_private {
        s32 csr14;                          /* Saved SIA TX/RX Register     */
        s32 csr15;                          /* Saved SIA General Register   */
        int save_cnt;                       /* Flag if state already saved  */
-       struct sk_buff *skb;                /* Save the (re-ordered) skb's  */
+       struct sk_buff_head queue;          /* Save the (re-ordered) skb's  */
     } cache;
     struct de4x5_srom srom;                 /* A copy of the SROM           */
     int cfrv;                              /* Card CFRV copy */
@@ -1128,6 +1128,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
        printk("      which has an Ethernet PROM CRC error.\n");
        return -ENXIO;
     } else {
+       skb_queue_head_init(&lp->cache.queue);
        lp->cache.gepc = GEP_INIT;
        lp->asBit = GEP_SLNK;
        lp->asPolarity = GEP_SLNK;
@@ -1487,7 +1488,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
        }
     } else if (skb->len > 0) {
        /* If we already have stuff queued locally, use that first */
-       if (lp->cache.skb && !lp->interrupt) {
+       if (!skb_queue_empty(&lp->cache.queue) && !lp->interrupt) {
            de4x5_put_cache(dev, skb);
            skb = de4x5_get_cache(dev);
        }
@@ -1580,7 +1581,7 @@ de4x5_interrupt(int irq, void *dev_id)
 
     /* Load the TX ring with any locally stored packets */
     if (!test_and_set_bit(0, (void *)&lp->cache.lock)) {
-       while (lp->cache.skb && !netif_queue_stopped(dev) && lp->tx_enable) {
+       while (!skb_queue_empty(&lp->cache.queue) && !netif_queue_stopped(dev) && lp->tx_enable) {
            de4x5_queue_pkt(de4x5_get_cache(dev), dev);
        }
        lp->cache.lock = 0;
@@ -3679,11 +3680,7 @@ de4x5_free_tx_buffs(struct net_device *dev)
     }
 
     /* Unload the locally queued packets */
-    while (lp->cache.skb) {
-       dev_kfree_skb(de4x5_get_cache(dev));
-    }
-
-    return;
+    __skb_queue_purge(&lp->cache.queue);
 }
 
 /*
@@ -3781,43 +3778,24 @@ static void
 de4x5_put_cache(struct net_device *dev, struct sk_buff *skb)
 {
     struct de4x5_private *lp = netdev_priv(dev);
-    struct sk_buff *p;
-
-    if (lp->cache.skb) {
-       for (p=lp->cache.skb; p->next; p=p->next);
-       p->next = skb;
-    } else {
-       lp->cache.skb = skb;
-    }
-    skb->next = NULL;
 
-    return;
+    __skb_queue_tail(&lp->cache.queue, skb);
 }
 
 static void
 de4x5_putb_cache(struct net_device *dev, struct sk_buff *skb)
 {
     struct de4x5_private *lp = netdev_priv(dev);
-    struct sk_buff *p = lp->cache.skb;
-
-    lp->cache.skb = skb;
-    skb->next = p;
 
-    return;
+    __skb_queue_head(&lp->cache.queue, skb);
 }
 
 static struct sk_buff *
 de4x5_get_cache(struct net_device *dev)
 {
     struct de4x5_private *lp = netdev_priv(dev);
-    struct sk_buff *p = lp->cache.skb;
 
-    if (p) {
-       lp->cache.skb = p->next;
-       p->next = NULL;
-    }
-
-    return p;
+    return __skb_dequeue(&lp->cache.queue);
 }
 
 /*
index 8f944e57fd55932e0fcc0b21ba51c6fdb0dc8a84..c87747bb24c55eb9ea2ac58992eabfdf348b664b 100644 (file)
@@ -400,7 +400,7 @@ static struct enet_addr_container *get_enet_addr_container(void)
        enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL);
        if (!enet_addr_cont) {
                ugeth_err("%s: No memory for enet_addr_container object.",
-                         __FUNCTION__);
+                         __func__);
                return NULL;
        }
 
@@ -427,7 +427,7 @@ static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth,
        struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
 
        if (!(paddr_num < NUM_OF_PADDRS)) {
-               ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__);
+               ugeth_warn("%s: Illegal paddr_num.", __func__);
                return -EINVAL;
        }
 
@@ -447,7 +447,7 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
        struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 
        if (!(paddr_num < NUM_OF_PADDRS)) {
-               ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
+               ugeth_warn("%s: Illagel paddr_num.", __func__);
                return -EINVAL;
        }
 
@@ -1441,7 +1441,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
        u32 upsmr, maccfg2, tbiBaseAddress;
        u16 value;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        ug_info = ugeth->ug_info;
        ug_regs = ugeth->ug_regs;
@@ -1504,7 +1504,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
        if (ret_val != 0) {
                if (netif_msg_probe(ugeth))
                        ugeth_err("%s: Preamble length must be between 3 and 7 inclusive.",
-                            __FUNCTION__);
+                            __func__);
                return ret_val;
        }
 
@@ -1744,7 +1744,7 @@ static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
        /* check if the UCC number is in range. */
        if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
                if (netif_msg_probe(ugeth))
-                       ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+                       ugeth_err("%s: ucc_num out of range.", __func__);
                return -EINVAL;
        }
 
@@ -1773,7 +1773,7 @@ static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
        /* check if the UCC number is in range. */
        if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
                if (netif_msg_probe(ugeth))
-                       ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+                       ugeth_err("%s: ucc_num out of range.", __func__);
                return -EINVAL;
        }
 
@@ -2062,7 +2062,7 @@ static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth
                ugeth_warn
                    ("%s: multicast address added to paddr will have no "
                     "effect - is this what you wanted?",
-                    __FUNCTION__);
+                    __func__);
 
        ugeth->indAddrRegUsed[paddr_num] = 1;   /* mark this paddr as used */
        /* store address in our database */
@@ -2278,7 +2278,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
        struct phy_device *phydev = ugeth->phydev;
        u32 tempval;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        /* Disable the controller */
        ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
@@ -2315,7 +2315,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
              (uf_info->bd_mem_part == MEM_PART_MURAM))) {
                if (netif_msg_probe(ugeth))
                        ugeth_err("%s: Bad memory partition value.",
-                                       __FUNCTION__);
+                                       __func__);
                return -EINVAL;
        }
 
@@ -2327,7 +2327,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
                        if (netif_msg_probe(ugeth))
                                ugeth_err
                                    ("%s: Rx BD ring length must be multiple of 4, no smaller than 8.",
-                                       __FUNCTION__);
+                                       __func__);
                        return -EINVAL;
                }
        }
@@ -2338,7 +2338,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
                        if (netif_msg_probe(ugeth))
                                ugeth_err
                                    ("%s: Tx BD ring length must be no smaller than 2.",
-                                    __FUNCTION__);
+                                    __func__);
                        return -EINVAL;
                }
        }
@@ -2349,21 +2349,21 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
                if (netif_msg_probe(ugeth))
                        ugeth_err
                            ("%s: max_rx_buf_length must be non-zero multiple of 128.",
-                            __FUNCTION__);
+                            __func__);
                return -EINVAL;
        }
 
        /* num Tx queues */
        if (ug_info->numQueuesTx > NUM_TX_QUEUES) {
                if (netif_msg_probe(ugeth))
-                       ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
+                       ugeth_err("%s: number of tx queues too large.", __func__);
                return -EINVAL;
        }
 
        /* num Rx queues */
        if (ug_info->numQueuesRx > NUM_RX_QUEUES) {
                if (netif_msg_probe(ugeth))
-                       ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
+                       ugeth_err("%s: number of rx queues too large.", __func__);
                return -EINVAL;
        }
 
@@ -2374,7 +2374,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
                                ugeth_err
                                    ("%s: VLAN priority table entry must not be"
                                        " larger than number of Rx queues.",
-                                    __FUNCTION__);
+                                    __func__);
                        return -EINVAL;
                }
        }
@@ -2386,7 +2386,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
                                ugeth_err
                                    ("%s: IP priority table entry must not be"
                                        " larger than number of Rx queues.",
-                                    __FUNCTION__);
+                                    __func__);
                        return -EINVAL;
                }
        }
@@ -2394,7 +2394,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
        if (ug_info->cam && !ug_info->ecamptr) {
                if (netif_msg_probe(ugeth))
                        ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
-                                 __FUNCTION__);
+                                 __func__);
                return -EINVAL;
        }
 
@@ -2404,7 +2404,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
                if (netif_msg_probe(ugeth))
                        ugeth_err("%s: Number of station addresses greater than 1 "
                                  "not allowed in extended parsing mode.",
-                                 __FUNCTION__);
+                                 __func__);
                return -EINVAL;
        }
 
@@ -2418,7 +2418,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
        /* Initialize the general fast UCC block. */
        if (ucc_fast_init(uf_info, &ugeth->uccf)) {
                if (netif_msg_probe(ugeth))
-                       ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
+                       ugeth_err("%s: Failed to init uccf.", __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -2448,7 +2448,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
        u8 __iomem *endOfRing;
        u8 numThreadsRxNumerical, numThreadsTxNumerical;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
        uccf = ugeth->uccf;
        ug_info = ugeth->ug_info;
        uf_info = &ug_info->uf_info;
@@ -2474,7 +2474,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
        default:
                if (netif_msg_ifup(ugeth))
                        ugeth_err("%s: Bad number of Rx threads value.",
-                                       __FUNCTION__);
+                                       __func__);
                ucc_geth_memclean(ugeth);
                return -EINVAL;
                break;
@@ -2499,7 +2499,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
        default:
                if (netif_msg_ifup(ugeth))
                        ugeth_err("%s: Bad number of Tx threads value.",
-                                       __FUNCTION__);
+                                       __func__);
                ucc_geth_memclean(ugeth);
                return -EINVAL;
                break;
@@ -2553,7 +2553,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
        if (ret_val != 0) {
                if (netif_msg_ifup(ugeth))
                        ugeth_err("%s: IPGIFG initialization parameter too large.",
-                                 __FUNCTION__);
+                                 __func__);
                ucc_geth_memclean(ugeth);
                return ret_val;
        }
@@ -2571,7 +2571,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
        if (ret_val != 0) {
                if (netif_msg_ifup(ugeth))
                        ugeth_err("%s: Half Duplex initialization parameter too large.",
-                         __FUNCTION__);
+                         __func__);
                ucc_geth_memclean(ugeth);
                return ret_val;
        }
@@ -2626,7 +2626,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                        if (netif_msg_ifup(ugeth))
                                ugeth_err
                                    ("%s: Can not allocate memory for Tx bd rings.",
-                                    __FUNCTION__);
+                                    __func__);
                        ucc_geth_memclean(ugeth);
                        return -ENOMEM;
                }
@@ -2662,7 +2662,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                        if (netif_msg_ifup(ugeth))
                                ugeth_err
                                    ("%s: Can not allocate memory for Rx bd rings.",
-                                    __FUNCTION__);
+                                    __func__);
                        ucc_geth_memclean(ugeth);
                        return -ENOMEM;
                }
@@ -2678,7 +2678,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (ugeth->tx_skbuff[j] == NULL) {
                        if (netif_msg_ifup(ugeth))
                                ugeth_err("%s: Could not allocate tx_skbuff",
-                                         __FUNCTION__);
+                                         __func__);
                        ucc_geth_memclean(ugeth);
                        return -ENOMEM;
                }
@@ -2710,7 +2710,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (ugeth->rx_skbuff[j] == NULL) {
                        if (netif_msg_ifup(ugeth))
                                ugeth_err("%s: Could not allocate rx_skbuff",
-                                         __FUNCTION__);
+                                         __func__);
                        ucc_geth_memclean(ugeth);
                        return -ENOMEM;
                }
@@ -2744,7 +2744,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
-                            __FUNCTION__);
+                            __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -2767,7 +2767,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
-                            __FUNCTION__);
+                            __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -2797,7 +2797,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
-                            __FUNCTION__);
+                            __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -2841,7 +2841,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                        if (netif_msg_ifup(ugeth))
                                ugeth_err
                                 ("%s: Can not allocate DPRAM memory for p_scheduler.",
-                                    __FUNCTION__);
+                                    __func__);
                        ucc_geth_memclean(ugeth);
                        return -ENOMEM;
                }
@@ -2892,7 +2892,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                                ugeth_err
                                    ("%s: Can not allocate DPRAM memory for"
                                        " p_tx_fw_statistics_pram.",
-                                       __FUNCTION__);
+                                       __func__);
                        ucc_geth_memclean(ugeth);
                        return -ENOMEM;
                }
@@ -2932,7 +2932,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
-                            __FUNCTION__);
+                            __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -2954,7 +2954,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
-                            __FUNCTION__);
+                            __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -2978,7 +2978,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                        if (netif_msg_ifup(ugeth))
                                ugeth_err
                                        ("%s: Can not allocate DPRAM memory for"
-                                       " p_rx_fw_statistics_pram.", __FUNCTION__);
+                                       " p_rx_fw_statistics_pram.", __func__);
                        ucc_geth_memclean(ugeth);
                        return -ENOMEM;
                }
@@ -3001,7 +3001,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate DPRAM memory for"
-                               " p_rx_irq_coalescing_tbl.", __FUNCTION__);
+                               " p_rx_irq_coalescing_tbl.", __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -3070,7 +3070,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
-                            __FUNCTION__);
+                            __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -3147,7 +3147,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (!ug_info->extendedFilteringChainPointer) {
                        if (netif_msg_ifup(ugeth))
                                ugeth_err("%s: Null Extended Filtering Chain Pointer.",
-                                         __FUNCTION__);
+                                         __func__);
                        ucc_geth_memclean(ugeth);
                        return -EINVAL;
                }
@@ -3161,7 +3161,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                        if (netif_msg_ifup(ugeth))
                                ugeth_err
                                        ("%s: Can not allocate DPRAM memory for"
-                                       " p_exf_glbl_param.", __FUNCTION__);
+                                       " p_exf_glbl_param.", __func__);
                        ucc_geth_memclean(ugeth);
                        return -ENOMEM;
                }
@@ -3209,7 +3209,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate memory for"
-                               " p_UccInitEnetParamShadows.", __FUNCTION__);
+                               " p_UccInitEnetParamShadows.", __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -3244,7 +3244,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
                if (netif_msg_ifup(ugeth))
                        ugeth_err("%s: Invalid largest External Lookup Key Size.",
-                                 __FUNCTION__);
+                                 __func__);
                ucc_geth_memclean(ugeth);
                return -EINVAL;
        }
@@ -3271,7 +3271,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                ug_info->riscRx, 1)) != 0) {
                if (netif_msg_ifup(ugeth))
                                ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
-                                       __FUNCTION__);
+                                       __func__);
                ucc_geth_memclean(ugeth);
                return ret_val;
        }
@@ -3287,7 +3287,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                                    ug_info->riscTx, 0)) != 0) {
                if (netif_msg_ifup(ugeth))
                        ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
-                                 __FUNCTION__);
+                                 __func__);
                ucc_geth_memclean(ugeth);
                return ret_val;
        }
@@ -3297,7 +3297,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) {
                        if (netif_msg_ifup(ugeth))
                                ugeth_err("%s: Can not fill Rx bds with buffers.",
-                                         __FUNCTION__);
+                                         __func__);
                        ucc_geth_memclean(ugeth);
                        return ret_val;
                }
@@ -3309,7 +3309,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
                if (netif_msg_ifup(ugeth))
                        ugeth_err
                            ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
-                            __FUNCTION__);
+                            __func__);
                ucc_geth_memclean(ugeth);
                return -ENOMEM;
        }
@@ -3360,7 +3360,7 @@ static void ucc_geth_timeout(struct net_device *dev)
 {
        struct ucc_geth_private *ugeth = netdev_priv(dev);
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        dev->stats.tx_errors++;
 
@@ -3386,7 +3386,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
        u32 bd_status;
        u8 txQ = 0;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        spin_lock_irq(&ugeth->lock);
 
@@ -3459,7 +3459,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
        u8 *bdBuffer;
        struct net_device *dev;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        dev = ugeth->dev;
 
@@ -3481,7 +3481,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
                    (bd_status & R_ERRORS_FATAL)) {
                        if (netif_msg_rx_err(ugeth))
                                ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
-                                          __FUNCTION__, __LINE__, (u32) skb);
+                                          __func__, __LINE__, (u32) skb);
                        if (skb)
                                dev_kfree_skb_any(skb);
 
@@ -3507,7 +3507,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
                skb = get_new_skb(ugeth, bd);
                if (!skb) {
                        if (netif_msg_rx_err(ugeth))
-                               ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
+                               ugeth_warn("%s: No Rx Data Buffer", __func__);
                        dev->stats.rx_dropped++;
                        break;
                }
@@ -3613,7 +3613,7 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
        register u32 tx_mask;
        u8 i;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        uccf = ugeth->uccf;
        ug_info = ugeth->ug_info;
@@ -3683,13 +3683,13 @@ static int ucc_geth_open(struct net_device *dev)
        struct ucc_geth_private *ugeth = netdev_priv(dev);
        int err;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        /* Test station address */
        if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
                if (netif_msg_ifup(ugeth))
                        ugeth_err("%s: Multicast address used for station address"
-                                 " - is this what you wanted?", __FUNCTION__);
+                                 " - is this what you wanted?", __func__);
                return -EINVAL;
        }
 
@@ -3772,7 +3772,7 @@ static int ucc_geth_close(struct net_device *dev)
 {
        struct ucc_geth_private *ugeth = netdev_priv(dev);
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        napi_disable(&ugeth->napi);
 
@@ -3840,7 +3840,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
                PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
        };
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        prop = of_get_property(np, "cell-index", NULL);
        if (!prop) {
@@ -3857,7 +3857,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
        if (ug_info == NULL) {
                if (netif_msg_probe(&debug))
                        ugeth_err("%s: [%d] Missing additional data!",
-                                       __FUNCTION__, ucc_num);
+                                       __func__, ucc_num);
                return -ENODEV;
        }
 
index 6e42b5a8c22bb540ba9827f72ee482893c1972d4..1164c52e2c0a569f87fb9b01b9fa287833e33906 100644 (file)
@@ -92,9 +92,6 @@
 
 #define        HSO_NET_TX_TIMEOUT              (HZ*10)
 
-/* Serial port defines and structs. */
-#define HSO_SERIAL_FLAG_RX_SENT                0
-
 #define HSO_SERIAL_MAGIC               0x48534f31
 
 /* Number of ttys to handle */
@@ -179,6 +176,12 @@ struct hso_net {
        unsigned long flags;
 };
 
+enum rx_ctrl_state{
+       RX_IDLE,
+       RX_SENT,
+       RX_PENDING
+};
+
 struct hso_serial {
        struct hso_device *parent;
        int magic;
@@ -205,7 +208,7 @@ struct hso_serial {
        struct usb_endpoint_descriptor *in_endp;
        struct usb_endpoint_descriptor *out_endp;
 
-       unsigned long flags;
+       enum rx_ctrl_state rx_state;
        u8 rts_state;
        u8 dtr_state;
        unsigned tx_urb_used:1;
@@ -216,6 +219,15 @@ struct hso_serial {
        spinlock_t serial_lock;
 
        int (*write_data) (struct hso_serial *serial);
+       /* Hacks required to get flow control
+        * working on the serial receive buffers
+        * so as not to drop characters on the floor.
+        */
+       int  curr_rx_urb_idx;
+       u16  curr_rx_urb_offset;
+       u8   rx_urb_filled[MAX_RX_URBS];
+       struct tasklet_struct unthrottle_tasklet;
+       struct work_struct    retry_unthrottle_workqueue;
 };
 
 struct hso_device {
@@ -271,7 +283,7 @@ struct hso_device {
 static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file,
                               unsigned int set, unsigned int clear);
 static void ctrl_callback(struct urb *urb);
-static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
+static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial);
 static void hso_kick_transmit(struct hso_serial *serial);
 /* Helper functions */
 static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int,
@@ -287,6 +299,8 @@ static int hso_start_net_device(struct hso_device *hso_dev);
 static void hso_free_shared_int(struct hso_shared_int *shared_int);
 static int hso_stop_net_device(struct hso_device *hso_dev);
 static void hso_serial_ref_free(struct kref *ref);
+static void hso_std_serial_read_bulk_callback(struct urb *urb);
+static int hso_mux_serial_read(struct hso_serial *serial);
 static void async_get_intf(struct work_struct *data);
 static void async_put_intf(struct work_struct *data);
 static int hso_put_activity(struct hso_device *hso_dev);
@@ -458,6 +472,17 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev,
 }
 static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL);
 
+static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb)
+{
+       int idx;
+
+       for (idx = 0; idx < serial->num_rx_urbs; idx++)
+               if (serial->rx_urb[idx] == urb)
+                       return idx;
+       dev_err(serial->parent->dev, "hso_urb_to_index failed\n");
+       return -1;
+}
+
 /* converts mux value to a port spec value */
 static u32 hso_mux_to_port(int mux)
 {
@@ -1039,6 +1064,158 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
        return;
 }
 
+static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb)
+{
+       int result;
+#ifdef CONFIG_HSO_AUTOPM
+       usb_mark_last_busy(urb->dev);
+#endif
+       /* We are done with this URB, resubmit it. Prep the USB to wait for
+        * another frame */
+       usb_fill_bulk_urb(urb, serial->parent->usb,
+                         usb_rcvbulkpipe(serial->parent->usb,
+                                         serial->in_endp->
+                                         bEndpointAddress & 0x7F),
+                         urb->transfer_buffer, serial->rx_data_length,
+                         hso_std_serial_read_bulk_callback, serial);
+       /* Give this to the USB subsystem so it can tell us when more data
+        * arrives. */
+       result = usb_submit_urb(urb, GFP_ATOMIC);
+       if (result) {
+               dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d\n",
+                       __func__, result);
+       }
+}
+
+
+
+
+static void put_rxbuf_data_and_resubmit_bulk_urb(struct hso_serial *serial)
+{
+       int count;
+       struct urb *curr_urb;
+
+       while (serial->rx_urb_filled[serial->curr_rx_urb_idx]) {
+               curr_urb = serial->rx_urb[serial->curr_rx_urb_idx];
+               count = put_rxbuf_data(curr_urb, serial);
+               if (count == -1)
+                       return;
+               if (count == 0) {
+                       serial->curr_rx_urb_idx++;
+                       if (serial->curr_rx_urb_idx >= serial->num_rx_urbs)
+                               serial->curr_rx_urb_idx = 0;
+                       hso_resubmit_rx_bulk_urb(serial, curr_urb);
+               }
+       }
+}
+
+static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial)
+{
+       int count = 0;
+       struct urb *urb;
+
+       urb = serial->rx_urb[0];
+       if (serial->open_count > 0) {
+               count = put_rxbuf_data(urb, serial);
+               if (count == -1)
+                       return;
+       }
+       /* Re issue a read as long as we receive data. */
+
+       if (count == 0 && ((urb->actual_length != 0) ||
+                          (serial->rx_state == RX_PENDING))) {
+               serial->rx_state = RX_SENT;
+               hso_mux_serial_read(serial);
+       } else
+               serial->rx_state = RX_IDLE;
+}
+
+
+/* read callback for Diag and CS port */
+static void hso_std_serial_read_bulk_callback(struct urb *urb)
+{
+       struct hso_serial *serial = urb->context;
+       int status = urb->status;
+
+       /* sanity check */
+       if (!serial) {
+               D1("serial == NULL");
+               return;
+       } else if (status) {
+               log_usb_status(status, __func__);
+               return;
+       }
+
+       D4("\n--- Got serial_read_bulk callback %02x ---", status);
+       D1("Actual length = %d\n", urb->actual_length);
+       DUMP1(urb->transfer_buffer, urb->actual_length);
+
+       /* Anyone listening? */
+       if (serial->open_count == 0)
+               return;
+
+       if (status == 0) {
+               if (serial->parent->port_spec & HSO_INFO_CRC_BUG) {
+                       u32 rest;
+                       u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
+                       rest =
+                           urb->actual_length %
+                           serial->in_endp->wMaxPacketSize;
+                       if (((rest == 5) || (rest == 6))
+                           && !memcmp(((u8 *) urb->transfer_buffer) +
+                                      urb->actual_length - 4, crc_check, 4)) {
+                               urb->actual_length -= 4;
+                       }
+               }
+               /* Valid data, handle RX data */
+               spin_lock(&serial->serial_lock);
+               serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1;
+               put_rxbuf_data_and_resubmit_bulk_urb(serial);
+               spin_unlock(&serial->serial_lock);
+       } else if (status == -ENOENT || status == -ECONNRESET) {
+               /* Unlinked - check for throttled port. */
+               D2("Port %d, successfully unlinked urb", serial->minor);
+               spin_lock(&serial->serial_lock);
+               serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
+               hso_resubmit_rx_bulk_urb(serial, urb);
+               spin_unlock(&serial->serial_lock);
+       } else {
+               D2("Port %d, status = %d for read urb", serial->minor, status);
+               return;
+       }
+}
+
+/*
+ * This needs to be a tasklet otherwise we will
+ * end up recursively calling this function.
+ */
+void hso_unthrottle_tasklet(struct hso_serial *serial)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&serial->serial_lock, flags);
+       if ((serial->parent->port_spec & HSO_INTF_MUX))
+               put_rxbuf_data_and_resubmit_ctrl_urb(serial);
+       else
+               put_rxbuf_data_and_resubmit_bulk_urb(serial);
+       spin_unlock_irqrestore(&serial->serial_lock, flags);
+}
+
+static void hso_unthrottle(struct tty_struct *tty)
+{
+       struct hso_serial *serial = get_serial_by_tty(tty);
+
+       tasklet_hi_schedule(&serial->unthrottle_tasklet);
+}
+
+void hso_unthrottle_workfunc(struct work_struct *work)
+{
+       struct hso_serial *serial =
+           container_of(work, struct hso_serial,
+                        retry_unthrottle_workqueue);
+       hso_unthrottle_tasklet(serial);
+}
+
 /* open the requested serial port */
 static int hso_serial_open(struct tty_struct *tty, struct file *filp)
 {
@@ -1064,13 +1241,18 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
        tty->driver_data = serial;
        serial->tty = tty;
 
-       /* check for port allready opened, if not set the termios */
+       /* check for port already opened, if not set the termios */
        serial->open_count++;
        if (serial->open_count == 1) {
                tty->low_latency = 1;
-               serial->flags = 0;
+               serial->rx_state = RX_IDLE;
                /* Force default termio settings */
                _hso_serial_set_termios(tty, NULL);
+               tasklet_init(&serial->unthrottle_tasklet,
+                            (void (*)(unsigned long))hso_unthrottle_tasklet,
+                            (unsigned long)serial);
+               INIT_WORK(&serial->retry_unthrottle_workqueue,
+                         hso_unthrottle_workfunc);
                result = hso_start_serial_device(serial->parent, GFP_KERNEL);
                if (result) {
                        hso_stop_serial_device(serial->parent);
@@ -1117,9 +1299,13 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
                }
                if (!usb_gone)
                        hso_stop_serial_device(serial->parent);
+               tasklet_kill(&serial->unthrottle_tasklet);
+               cancel_work_sync(&serial->retry_unthrottle_workqueue);
        }
+
        if (!usb_gone)
                usb_autopm_put_interface(serial->parent->interface);
+
        mutex_unlock(&serial->parent->mutex);
 }
 
@@ -1422,15 +1608,21 @@ static void intr_callback(struct urb *urb)
                                                                   (1 << i));
                        if (serial != NULL) {
                                D1("Pending read interrupt on port %d\n", i);
-                               if (!test_and_set_bit(HSO_SERIAL_FLAG_RX_SENT,
-                                                     &serial->flags)) {
+                               spin_lock(&serial->serial_lock);
+                               if (serial->rx_state == RX_IDLE) {
                                        /* Setup and send a ctrl req read on
                                         * port i */
-                                       hso_mux_serial_read(serial);
+                               if (!serial->rx_urb_filled[0]) {
+                                               serial->rx_state = RX_SENT;
+                                               hso_mux_serial_read(serial);
+                                       } else
+                                               serial->rx_state = RX_PENDING;
+
                                } else {
                                        D1("Already pending a read on "
                                           "port %d\n", i);
                                }
+                               spin_unlock(&serial->serial_lock);
                        }
                }
        }
@@ -1532,16 +1724,10 @@ static void ctrl_callback(struct urb *urb)
        if (req->bRequestType ==
            (USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) {
                /* response to a read command */
-               if (serial->open_count > 0) {
-                       /* handle RX data the normal way */
-                       put_rxbuf_data(urb, serial);
-               }
-
-               /* Re issue a read as long as we receive data. */
-               if (urb->actual_length != 0)
-                       hso_mux_serial_read(serial);
-               else
-                       clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
+               serial->rx_urb_filled[0] = 1;
+               spin_lock(&serial->serial_lock);
+               put_rxbuf_data_and_resubmit_ctrl_urb(serial);
+               spin_unlock(&serial->serial_lock);
        } else {
                hso_put_activity(serial->parent);
                if (serial->tty)
@@ -1552,91 +1738,42 @@ static void ctrl_callback(struct urb *urb)
 }
 
 /* handle RX data for serial port */
-static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
+static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial)
 {
        struct tty_struct *tty = serial->tty;
-
+       int write_length_remaining = 0;
+       int curr_write_len;
        /* Sanity check */
        if (urb == NULL || serial == NULL) {
                D1("serial = NULL");
-               return;
+               return -2;
        }
 
        /* Push data to tty */
-       if (tty && urb->actual_length) {
+       if (tty) {
+               write_length_remaining = urb->actual_length -
+                       serial->curr_rx_urb_offset;
                D1("data to push to tty");
-               tty_insert_flip_string(tty, urb->transfer_buffer,
-                                      urb->actual_length);
-               tty_flip_buffer_push(tty);
-       }
-}
-
-/* read callback for Diag and CS port */
-static void hso_std_serial_read_bulk_callback(struct urb *urb)
-{
-       struct hso_serial *serial = urb->context;
-       int result;
-       int status = urb->status;
-
-       /* sanity check */
-       if (!serial) {
-               D1("serial == NULL");
-               return;
-       } else if (status) {
-               log_usb_status(status, __func__);
-               return;
-       }
-
-       D4("\n--- Got serial_read_bulk callback %02x ---", status);
-       D1("Actual length = %d\n", urb->actual_length);
-       DUMP1(urb->transfer_buffer, urb->actual_length);
-
-       /* Anyone listening? */
-       if (serial->open_count == 0)
-               return;
-
-       if (status == 0) {
-               if (serial->parent->port_spec & HSO_INFO_CRC_BUG) {
-                       u32 rest;
-                       u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF };
-                       rest =
-                           urb->actual_length %
-                           serial->in_endp->wMaxPacketSize;
-                       if (((rest == 5) || (rest == 6))
-                           && !memcmp(((u8 *) urb->transfer_buffer) +
-                                      urb->actual_length - 4, crc_check, 4)) {
-                               urb->actual_length -= 4;
-                       }
+               while (write_length_remaining) {
+                       if (test_bit(TTY_THROTTLED, &tty->flags))
+                               return -1;
+                       curr_write_len =  tty_insert_flip_string
+                               (tty, urb->transfer_buffer +
+                                serial->curr_rx_urb_offset,
+                                write_length_remaining);
+                       serial->curr_rx_urb_offset += curr_write_len;
+                       write_length_remaining -= curr_write_len;
+                       tty_flip_buffer_push(tty);
                }
-               /* Valid data, handle RX data */
-               put_rxbuf_data(urb, serial);
-       } else if (status == -ENOENT || status == -ECONNRESET) {
-               /* Unlinked - check for throttled port. */
-               D2("Port %d, successfully unlinked urb", serial->minor);
-       } else {
-               D2("Port %d, status = %d for read urb", serial->minor, status);
-               return;
        }
-
-       usb_mark_last_busy(urb->dev);
-
-       /* We are done with this URB, resubmit it. Prep the USB to wait for
-        * another frame */
-       usb_fill_bulk_urb(urb, serial->parent->usb,
-                         usb_rcvbulkpipe(serial->parent->usb,
-                                         serial->in_endp->
-                                         bEndpointAddress & 0x7F),
-                         urb->transfer_buffer, serial->rx_data_length,
-                         hso_std_serial_read_bulk_callback, serial);
-       /* Give this to the USB subsystem so it can tell us when more data
-        * arrives. */
-       result = usb_submit_urb(urb, GFP_ATOMIC);
-       if (result) {
-               dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d",
-                       __func__, result);
+       if (write_length_remaining == 0) {
+               serial->curr_rx_urb_offset = 0;
+               serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0;
        }
+       return write_length_remaining;
 }
 
+
 /* Base driver functions */
 
 static void hso_log_port(struct hso_device *hso_dev)
@@ -1794,9 +1931,13 @@ static int hso_stop_serial_device(struct hso_device *hso_dev)
                return -ENODEV;
 
        for (i = 0; i < serial->num_rx_urbs; i++) {
-               if (serial->rx_urb[i])
+               if (serial->rx_urb[i]) {
                                usb_kill_urb(serial->rx_urb[i]);
+                               serial->rx_urb_filled[i] = 0;
+               }
        }
+       serial->curr_rx_urb_idx = 0;
+       serial->curr_rx_urb_offset = 0;
 
        if (serial->tx_urb)
                usb_kill_urb(serial->tx_urb);
@@ -2211,14 +2352,14 @@ static struct hso_device *hso_create_bulk_serial_device(
                                     USB_DIR_IN);
        if (!serial->in_endp) {
                dev_err(&interface->dev, "Failed to find BULK IN ep\n");
-               goto exit;
+               goto exit2;
        }
 
        if (!
            (serial->out_endp =
             hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) {
                dev_err(&interface->dev, "Failed to find BULK IN ep\n");
-               goto exit;
+               goto exit2;
        }
 
        serial->write_data = hso_std_serial_write_data;
@@ -2231,9 +2372,10 @@ static struct hso_device *hso_create_bulk_serial_device(
 
        /* done, return it */
        return hso_dev;
+
+exit2:
+       hso_serial_common_free(serial);
 exit:
-       if (hso_dev && serial)
-               hso_serial_common_free(serial);
        kfree(serial);
        hso_free_device(hso_dev);
        return NULL;
@@ -2740,6 +2882,7 @@ static const struct tty_operations hso_serial_ops = {
        .chars_in_buffer = hso_serial_chars_in_buffer,
        .tiocmget = hso_serial_tiocmget,
        .tiocmset = hso_serial_tiocmset,
+       .unthrottle = hso_unthrottle
 };
 
 static struct usb_driver hso_driver = {
index ca9d00c1194e0448da4945a00f2941a32bab8f75..b5143509e8be1f70e0433939d30ac44ef9a7e28f 100644 (file)
@@ -118,7 +118,7 @@ static void mcs7830_async_cmd_callback(struct urb *urb)
 
        if (urb->status < 0)
                printk(KERN_DEBUG "%s() failed with %d\n",
-                      __FUNCTION__, urb->status);
+                      __func__, urb->status);
 
        kfree(req);
        usb_free_urb(urb);
index 8c19307e50403b139ff2ad674bb94b222a263453..38b90e7a7ed30b52d04fe46f64411a2991c3b5b0 100644 (file)
@@ -119,7 +119,7 @@ static void ctrl_callback(struct urb *urb)
        default:
                if (netif_msg_drv(pegasus) && printk_ratelimit())
                        dev_dbg(&pegasus->intf->dev, "%s, status %d\n",
-                               __FUNCTION__, urb->status);
+                               __func__, urb->status);
        }
        pegasus->flags &= ~ETH_REGS_CHANGED;
        wake_up(&pegasus->ctrl_wait);
@@ -136,7 +136,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
        if (!buffer) {
                if (netif_msg_drv(pegasus))
                        dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
-                                       __FUNCTION__);
+                                       __func__);
                return -ENOMEM;
        }
        add_wait_queue(&pegasus->ctrl_wait, &wait);
@@ -224,7 +224,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size,
                        netif_device_detach(pegasus->net);
                if (netif_msg_drv(pegasus))
                        dev_err(&pegasus->intf->dev, "%s, status %d\n",
-                                       __FUNCTION__, ret);
+                                       __func__, ret);
                goto out;
        }
 
@@ -246,7 +246,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
        if (!tmp) {
                if (netif_msg_drv(pegasus))
                        dev_warn(&pegasus->intf->dev, "out of memory in %s\n",
-                                       __FUNCTION__);
+                                       __func__);
                return -ENOMEM;
        }
        memcpy(tmp, &data, 1);
@@ -277,7 +277,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data)
                        netif_device_detach(pegasus->net);
                if (netif_msg_drv(pegasus) && printk_ratelimit())
                        dev_err(&pegasus->intf->dev, "%s, status %d\n",
-                                       __FUNCTION__, ret);
+                                       __func__, ret);
                goto out;
        }
 
@@ -310,7 +310,7 @@ static int update_eth_regs_async(pegasus_t * pegasus)
                        netif_device_detach(pegasus->net);
                if (netif_msg_drv(pegasus))
                        dev_err(&pegasus->intf->dev, "%s, status %d\n",
-                                       __FUNCTION__, ret);
+                                       __func__, ret);
        }
 
        return ret;
@@ -341,7 +341,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd)
        }
 fail:
        if (netif_msg_drv(pegasus))
-               dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+               dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
 
        return ret;
 }
@@ -378,7 +378,7 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd)
 
 fail:
        if (netif_msg_drv(pegasus))
-               dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+               dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
        return -ETIMEDOUT;
 }
 
@@ -415,7 +415,7 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata)
 
 fail:
        if (netif_msg_drv(pegasus))
-               dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+               dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
        return -ETIMEDOUT;
 }
 
@@ -463,7 +463,7 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data)
                return ret;
 fail:
        if (netif_msg_drv(pegasus))
-               dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__);
+               dev_warn(&pegasus->intf->dev, "%s failed\n", __func__);
        return -ETIMEDOUT;
 }
 #endif                         /* PEGASUS_WRITE_EEPROM */
index 8463efb9e0b119417b8199c78c53d6a0151ffe43..02d25c743994e3f5539744587697ae1685187e16 100644 (file)
@@ -512,14 +512,13 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q)
        int                     count = 0;
 
        spin_lock_irqsave (&q->lock, flags);
-       for (skb = q->next; skb != (struct sk_buff *) q; skb = skbnext) {
+       skb_queue_walk_safe(q, skb, skbnext) {
                struct skb_data         *entry;
                struct urb              *urb;
                int                     retval;
 
                entry = (struct skb_data *) skb->cb;
                urb = entry->urb;
-               skbnext = skb->next;
 
                // during some PM-driven resume scenarios,
                // these (async) unlinks complete immediately
index 1b95b04c92576bf6d5c547489ab63f4c958fc548..29a33090d3d4d7775c44eea63f13d5bbe1881c1a 100644 (file)
@@ -1381,7 +1381,7 @@ enum velocity_msg_level {
 #define ASSERT(x) { \
        if (!(x)) { \
                printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\
-                       __FUNCTION__, __LINE__);\
+                       __func__, __LINE__);\
                BUG(); \
        }\
 }
index d14e6678deed2456be4df506a4094aaf4be20f68..a5ddc6c8963e3e189f65e8213e0110b9941841e6 100644 (file)
@@ -407,7 +407,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
        if (cfm->version != CFM_VERSION) {
                printk(KERN_ERR "%s:%s: firmware format %u rejected! "
                                "Expecting %u.\n",
-                               modname, __FUNCTION__, cfm->version, CFM_VERSION);
+                               modname, __func__, cfm->version, CFM_VERSION);
                return -EINVAL;
        }
 
@@ -420,7 +420,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
 */
        if (cksum != cfm->checksum) {
                printk(KERN_ERR "%s:%s: firmware corrupted!\n",
-                               modname, __FUNCTION__);
+                               modname, __func__);
                printk(KERN_ERR " cdsize = 0x%x (expected 0x%lx)\n",
                                len - (int)sizeof(struct cycx_firmware) - 1,
                                cfm->info.codesize);
@@ -432,7 +432,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
        /* If everything is ok, set reset, data and code pointers */
        img_hdr = (struct cycx_fw_header *)&cfm->image;
 #ifdef FIRMWARE_DEBUG
-       printk(KERN_INFO "%s:%s: image sizes\n", __FUNCTION__, modname);
+       printk(KERN_INFO "%s:%s: image sizes\n", __func__, modname);
        printk(KERN_INFO " reset=%lu\n", img_hdr->reset_size);
        printk(KERN_INFO "  data=%lu\n", img_hdr->data_size);
        printk(KERN_INFO "  code=%lu\n", img_hdr->code_size);
index d3b28b01b9f91c5e5e52cfb5eb9a60940cb07531..5a7303dc0965e7b5db3f8af3aa35202755602a51 100644 (file)
@@ -874,7 +874,7 @@ static void cycx_x25_irq_connect(struct cycx_device *card,
                nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
 
        dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
-                         __FUNCTION__, lcn, loc, rem);
+                         __func__, lcn, loc, rem);
 
        dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
        if (!dev) {
@@ -902,7 +902,7 @@ static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
        cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
        dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
-                         card->devname, __FUNCTION__, lcn, key);
+                         card->devname, __func__, lcn, key);
 
        dev = cycx_x25_get_dev_by_lcn(wandev, -key);
        if (!dev) {
@@ -929,7 +929,7 @@ static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
 
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
        dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
-                         card->devname, __FUNCTION__, lcn);
+                         card->devname, __func__, lcn);
        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
        if (!dev) {
                /* Invalid channel, discard packet */
@@ -950,7 +950,7 @@ static void cycx_x25_irq_disconnect(struct cycx_device *card,
        u8 lcn;
 
        cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
-       dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn);
+       dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn);
 
        dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
        if (dev) {
@@ -1381,7 +1381,7 @@ static void cycx_x25_chan_timer(unsigned long d)
                cycx_x25_chan_disconnect(dev);
        else
                printk(KERN_ERR "%s: %s for svc (%s) not connected!\n",
-                               chan->card->devname, __FUNCTION__, dev->name);
+                               chan->card->devname, __func__, dev->name);
 }
 
 /* Set logical channel state. */
@@ -1485,7 +1485,7 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
        unsigned char *ptr;
 
        if ((skb = dev_alloc_skb(1)) == NULL) {
-               printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
+               printk(KERN_ERR "%s: out of memory\n", __func__);
                return;
        }
 
index f5d55ad02267edb623128570104fbb8e095c8ff0..5f1ccb2b08b11d1dbe0f4a7cab308b6ec92105ef 100644 (file)
@@ -647,7 +647,7 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
 
        skb = dpriv->rx_skbuff[dpriv->rx_current++%RX_RING_SIZE];
        if (!skb) {
-               printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__);
+               printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __func__);
                goto refill;
        }
        pkt_len = TO_SIZE(le32_to_cpu(rx_fd->state2));
index 8b7e5d2e2ac94ced976d54587ba074142a13776a..cbcbf6f0414c9254aea1d14f95e7220b50ccab13 100644 (file)
@@ -163,15 +163,17 @@ static void x25_close(struct net_device *dev)
 
 static int x25_rx(struct sk_buff *skb)
 {
+       struct net_device *dev = skb->dev;
+
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
-               skb->dev->stats.rx_dropped++;
+               dev->stats.rx_dropped++;
                return NET_RX_DROP;
        }
 
-       if (lapb_data_received(skb->dev, skb) == LAPB_OK)
+       if (lapb_data_received(dev, skb) == LAPB_OK)
                return NET_RX_SUCCESS;
 
-       skb->dev->stats.rx_errors++;
+       dev->stats.rx_errors++;
        dev_kfree_skb_any(skb);
        return NET_RX_DROP;
 }
index 4518d0aa248026d62cdbe93e0afe579f6e161676..4917a94943bd9c1567bd63317b89043c3a08ccb3 100644 (file)
@@ -548,7 +548,7 @@ static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
 {
        st_cpc_tty_area    *cpc_tty; 
 
-       CPC_TTY_DBG("%s: set:%x clear:%x\n", __FUNCTION__, set, clear);
+       CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear);
 
        if (!tty || !tty->driver_data ) {
                CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n");  
index 6596cd0742b9dfd0256c4361d0fe3909b711d4f5..f972fef87c98839a9d3c8e1fc4f7c2516ed01199 100644 (file)
@@ -856,7 +856,7 @@ prepare_to_send( struct sk_buff  *skb,  struct net_device  *dev )
                len = SBNI_MIN_LEN;
 
        nl->tx_buf_p    = skb;
-       nl->tx_frameno  = (len + nl->maxframe - 1) / nl->maxframe;
+       nl->tx_frameno  = DIV_ROUND_UP(len, nl->maxframe);
        nl->framelen    = len < nl->maxframe  ?  len  :  nl->maxframe;
 
        outb( inb( dev->base_addr + CSR0 ) | TR_REQ,  dev->base_addr + CSR0 );
index ae58a12befd349a2e8445fcf2f20324395cf921b..370133e492d259431df941fc3eee94bb770fa117 100644 (file)
@@ -7107,7 +7107,7 @@ static int airo_get_aplist(struct net_device *dev,
  */
 static int airo_set_scan(struct net_device *dev,
                         struct iw_request_info *info,
-                        struct iw_param *vwrq,
+                        struct iw_point *dwrq,
                         char *extra)
 {
        struct airo_info *ai = dev->priv;
index f12355398fe7ca19186d976374c216e07a89c6bf..fd72e427cb2830183b729fbae965ee88b5003da2 100644 (file)
@@ -147,7 +147,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
        DEBUG(0, "airo_attach()\n");
 
        /* Interrupt setup */
-       p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
        p_dev->irq.Handler = NULL;
        
index 20018869051dd875dee5f5ac356055a0496ba37e..7134c40d6a69d49bc330333afe386925bb58d3af 100644 (file)
@@ -281,7 +281,9 @@ enum ath5k_radio {
        AR5K_RF5112     = 2,
        AR5K_RF2413     = 3,
        AR5K_RF5413     = 4,
-       AR5K_RF2425     = 5,
+       AR5K_RF2316     = 5,
+       AR5K_RF2317     = 6,
+       AR5K_RF2425     = 7,
 };
 
 /*
@@ -289,7 +291,7 @@ enum ath5k_radio {
  */
 
 enum ath5k_srev_type {
-       AR5K_VERSION_VER,
+       AR5K_VERSION_MAC,
        AR5K_VERSION_RAD,
 };
 
@@ -301,23 +303,24 @@ struct ath5k_srev_name {
 
 #define AR5K_SREV_UNKNOWN      0xffff
 
-#define AR5K_SREV_VER_AR5210   0x00
-#define AR5K_SREV_VER_AR5311   0x10
-#define AR5K_SREV_VER_AR5311A  0x20
-#define AR5K_SREV_VER_AR5311B  0x30
-#define AR5K_SREV_VER_AR5211   0x40
-#define AR5K_SREV_VER_AR5212   0x50
-#define AR5K_SREV_VER_AR5213   0x55
-#define AR5K_SREV_VER_AR5213A  0x59
-#define AR5K_SREV_VER_AR2413   0x78
-#define AR5K_SREV_VER_AR2414   0x79
-#define AR5K_SREV_VER_AR2424   0xa0 /* PCI-E */
-#define AR5K_SREV_VER_AR5424   0xa3 /* PCI-E */
-#define AR5K_SREV_VER_AR5413   0xa4
-#define AR5K_SREV_VER_AR5414   0xa5
-#define AR5K_SREV_VER_AR5416   0xc0 /* PCI-E */
-#define AR5K_SREV_VER_AR5418   0xca /* PCI-E */
-#define AR5K_SREV_VER_AR2425   0xe2 /* PCI-E */
+#define AR5K_SREV_AR5210       0x00 /* Crete */
+#define AR5K_SREV_AR5311       0x10 /* Maui 1 */
+#define AR5K_SREV_AR5311A      0x20 /* Maui 2 */
+#define AR5K_SREV_AR5311B      0x30 /* Spirit */
+#define AR5K_SREV_AR5211       0x40 /* Oahu */
+#define AR5K_SREV_AR5212       0x50 /* Venice */
+#define AR5K_SREV_AR5213       0x55 /* ??? */
+#define AR5K_SREV_AR5213A      0x59 /* Hainan */
+#define AR5K_SREV_AR2413       0x78 /* Griffin lite */
+#define AR5K_SREV_AR2414       0x70 /* Griffin */
+#define AR5K_SREV_AR5424       0x90 /* Condor */
+#define AR5K_SREV_AR5413       0xa4 /* Eagle lite */
+#define AR5K_SREV_AR5414       0xa0 /* Eagle */
+#define AR5K_SREV_AR2415       0xb0 /* Cobra */
+#define AR5K_SREV_AR5416       0xc0 /* PCI-E */
+#define AR5K_SREV_AR5418       0xca /* PCI-E */
+#define AR5K_SREV_AR2425       0xe0 /* Swan */
+#define AR5K_SREV_AR2417       0xf0 /* Nala */
 
 #define AR5K_SREV_RAD_5110     0x00
 #define AR5K_SREV_RAD_5111     0x10
@@ -329,10 +332,20 @@ struct ath5k_srev_name {
 #define AR5K_SREV_RAD_2112     0x40
 #define AR5K_SREV_RAD_2112A    0x45
 #define        AR5K_SREV_RAD_2112B     0x46
-#define AR5K_SREV_RAD_SC0      0x50    /* Found on 2413/2414 */
-#define AR5K_SREV_RAD_SC1      0x60    /* Found on 5413/5414 */
-#define AR5K_SREV_RAD_SC2      0xa0    /* Found on 2424-5/5424 */
-#define AR5K_SREV_RAD_5133     0xc0    /* MIMO found on 5418 */
+#define AR5K_SREV_RAD_2413     0x50
+#define AR5K_SREV_RAD_5413     0x60
+#define AR5K_SREV_RAD_2316     0x70
+#define AR5K_SREV_RAD_2317     0x80
+#define AR5K_SREV_RAD_5424     0xa0 /* Mostly same as 5413 */
+#define AR5K_SREV_RAD_2425     0xa2
+#define AR5K_SREV_RAD_5133     0xc0
+
+#define AR5K_SREV_PHY_5211     0x30
+#define AR5K_SREV_PHY_5212     0x41
+#define AR5K_SREV_PHY_2112B    0x43
+#define AR5K_SREV_PHY_2413     0x45
+#define AR5K_SREV_PHY_5413     0x61
+#define AR5K_SREV_PHY_2425     0x70
 
 /* IEEE defs */
 #define IEEE80211_MAX_LEN       2500
index 153c4111fabe3103e947c2418b129ab17bd03552..51d569883cdd787a7a9b3de3f567f4e415aa1ea1 100644 (file)
@@ -137,7 +137,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
        ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
 
        /*
-        * Set the mac revision based on the pci id
+        * Set the mac version based on the pci id
         */
        ah->ah_version = mac_version;
 
@@ -160,87 +160,132 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
                        0xffffffff;
        ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
                        CHANNEL_5GHZ);
+       ah->ah_phy = AR5K_PHY(0);
 
-       if (ah->ah_version == AR5K_AR5210)
-               ah->ah_radio_2ghz_revision = 0;
-       else
-               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                               CHANNEL_2GHZ);
-
-       /* Return on unsuported chips (unsupported eeprom etc) */
-       if ((srev >= AR5K_SREV_VER_AR5416) &&
-       (srev < AR5K_SREV_VER_AR2425)) {
-               ATH5K_ERR(sc, "Device not yet supported.\n");
-               ret = -ENODEV;
-               goto err_free;
-       } else if (srev == AR5K_SREV_VER_AR2425) {
-               ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
-       }
-
-       /* Identify single chip solutions */
-       if (((srev <= AR5K_SREV_VER_AR5414) &&
-       (srev >= AR5K_SREV_VER_AR2413)) ||
-       (srev == AR5K_SREV_VER_AR2425)) {
-               ah->ah_single_chip = true;
-       } else {
-               ah->ah_single_chip = false;
-       }
-
-       /* Single chip radio */
-       if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
-               ah->ah_radio_2ghz_revision = 0;
-
-       /* Identify the radio chip*/
-       if (ah->ah_version == AR5K_AR5210) {
-               ah->ah_radio = AR5K_RF5110;
-       /*
-        * Register returns 0x0/0x04 for radio revision
-        * so ath5k_hw_radio_revision doesn't parse the value
-        * correctly. For now we are based on mac's srev to
-        * identify RF2425 radio.
-        */
-       } else if (srev == AR5K_SREV_VER_AR2425) {
-               ah->ah_radio = AR5K_RF2425;
-               ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
-       } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
+       /* Try to identify radio chip based on it's srev */
+       switch (ah->ah_radio_5ghz_revision & 0xf0) {
+       case AR5K_SREV_RAD_5111:
                ah->ah_radio = AR5K_RF5111;
+               ah->ah_single_chip = false;
+               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                                                       CHANNEL_2GHZ);
                ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
-       } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
+               break;
+       case AR5K_SREV_RAD_5112:
+       case AR5K_SREV_RAD_2112:
                ah->ah_radio = AR5K_RF5112;
+               ah->ah_single_chip = false;
+               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                                                       CHANNEL_2GHZ);
                ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
-       } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
+               break;
+       case AR5K_SREV_RAD_2413:
                ah->ah_radio = AR5K_RF2413;
+               ah->ah_single_chip = true;
                ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
-       } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
+               break;
+       case AR5K_SREV_RAD_5413:
                ah->ah_radio = AR5K_RF5413;
+               ah->ah_single_chip = true;
                ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
-       } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
-               /* AR5424 */
-               if (srev >= AR5K_SREV_VER_AR5424) {
+               break;
+       case AR5K_SREV_RAD_2316:
+               ah->ah_radio = AR5K_RF2316;
+               ah->ah_single_chip = true;
+               ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
+               break;
+       case AR5K_SREV_RAD_2317:
+               ah->ah_radio = AR5K_RF2317;
+               ah->ah_single_chip = true;
+               ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317;
+               break;
+       case AR5K_SREV_RAD_5424:
+               if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
+               ah->ah_mac_version == AR5K_SREV_AR2417){
+                       ah->ah_radio = AR5K_RF2425;
+                       ah->ah_single_chip = true;
+                       ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
+               } else {
                        ah->ah_radio = AR5K_RF5413;
+                       ah->ah_single_chip = true;
                        ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
-               /* AR2424 */
-               } else {
-                       ah->ah_radio = AR5K_RF2413; /* For testing */
+               }
+               break;
+       default:
+               /* Identify radio based on mac/phy srev */
+               if (ah->ah_version == AR5K_AR5210) {
+                       ah->ah_radio = AR5K_RF5110;
+                       ah->ah_single_chip = false;
+               } else if (ah->ah_version == AR5K_AR5211) {
+                       ah->ah_radio = AR5K_RF5111;
+                       ah->ah_single_chip = false;
+                       ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                                                               CHANNEL_2GHZ);
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
+               ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
+               ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
+                       ah->ah_radio = AR5K_RF2425;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
+                       ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
+               } else if (srev == AR5K_SREV_AR5213A &&
+               ah->ah_phy_revision == AR5K_SREV_PHY_2112B) {
+                       ah->ah_radio = AR5K_RF5112;
+                       ah->ah_single_chip = false;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
+                       ah->ah_radio = AR5K_RF2316;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
+                       ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
+               ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
+                       ah->ah_radio = AR5K_RF5413;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
+                       ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
+               ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
+                       ah->ah_radio = AR5K_RF2413;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
                        ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
+               } else {
+                       ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
+                       ret = -ENODEV;
+                       goto err_free;
                }
        }
-       ah->ah_phy = AR5K_PHY(0);
+
+
+       /* Return on unsuported chips (unsupported eeprom etc) */
+       if ((srev >= AR5K_SREV_AR5416) &&
+       (srev < AR5K_SREV_AR2425)) {
+               ATH5K_ERR(sc, "Device not yet supported.\n");
+               ret = -ENODEV;
+               goto err_free;
+       }
 
        /*
         * Write PCI-E power save settings
         */
        if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
-               ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
-               ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
-               ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
-               ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
-               ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
-               ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
-               ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
-               ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
-               ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
-               ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
+               ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
+               /* Shut off RX when elecidle is asserted */
+               ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
+               /* TODO: EEPROM work */
+               ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
+               /* Shut off PLL and CLKREQ active in L1 */
+               ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
+               /* Preserce other settings */
+               ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
+               /* Reset SERDES to load new settings */
+               ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
+               mdelay(1);
        }
 
        /*
@@ -250,14 +295,13 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
        if (ret)
                goto err_free;
 
-       /* Write AR5K_PCICFG_UNK on 2112B and later chips */
-       if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B ||
-       srev > AR5K_SREV_VER_AR2413) {
-               ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG);
-       }
+       /* Enable pci core retry fix on Hainan (5213A) and later chips */
+       if (srev >= AR5K_SREV_AR5213A)
+               ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);
 
        /*
-        * Get card capabilities, values, ...
+        * Get card capabilities, calibration values etc
+        * TODO: EEPROM work
         */
        ret = ath5k_eeprom_init(ah);
        if (ret) {
@@ -273,7 +317,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
                goto err_free;
        }
 
-       /* Get MAC address */
+       /* Set MAC address */
        ret = ath5k_eeprom_read_mac(ah, mac);
        if (ret) {
                ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
index e09ed2ce67537c64c2d287f360c120eb1b80c8cd..c151588aa484df6746db95c20d4306519e6fd6d7 100644 (file)
@@ -72,7 +72,7 @@ MODULE_AUTHOR("Nick Kossifidis");
 MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
 MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
 MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION("0.5.0 (EXPERIMENTAL)");
+MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
 
 
 /* Known PCI ids */
@@ -93,41 +93,48 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
        { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
        { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
        { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
-       { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* 5424 Condor (PCI-E)*/
+       { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */
+       { PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */
        { 0 }
 };
 MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
 
 /* Known SREVs */
 static struct ath5k_srev_name srev_names[] = {
-       { "5210",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5210 },
-       { "5311",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5311 },
-       { "5311A",      AR5K_VERSION_VER,       AR5K_SREV_VER_AR5311A },
-       { "5311B",      AR5K_VERSION_VER,       AR5K_SREV_VER_AR5311B },
-       { "5211",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5211 },
-       { "5212",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5212 },
-       { "5213",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5213 },
-       { "5213A",      AR5K_VERSION_VER,       AR5K_SREV_VER_AR5213A },
-       { "2413",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR2413 },
-       { "2414",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR2414 },
-       { "2424",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR2424 },
-       { "5424",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5424 },
-       { "5413",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5413 },
-       { "5414",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5414 },
-       { "5416",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5416 },
-       { "5418",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR5418 },
-       { "2425",       AR5K_VERSION_VER,       AR5K_SREV_VER_AR2425 },
-       { "xxxxx",      AR5K_VERSION_VER,       AR5K_SREV_UNKNOWN },
+       { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
+       { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
+       { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
+       { "5311B",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311B },
+       { "5211",       AR5K_VERSION_MAC,       AR5K_SREV_AR5211 },
+       { "5212",       AR5K_VERSION_MAC,       AR5K_SREV_AR5212 },
+       { "5213",       AR5K_VERSION_MAC,       AR5K_SREV_AR5213 },
+       { "5213A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5213A },
+       { "2413",       AR5K_VERSION_MAC,       AR5K_SREV_AR2413 },
+       { "2414",       AR5K_VERSION_MAC,       AR5K_SREV_AR2414 },
+       { "5424",       AR5K_VERSION_MAC,       AR5K_SREV_AR5424 },
+       { "5413",       AR5K_VERSION_MAC,       AR5K_SREV_AR5413 },
+       { "5414",       AR5K_VERSION_MAC,       AR5K_SREV_AR5414 },
+       { "2415",       AR5K_VERSION_MAC,       AR5K_SREV_AR2415 },
+       { "5416",       AR5K_VERSION_MAC,       AR5K_SREV_AR5416 },
+       { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
+       { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
+       { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
+       { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
        { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
        { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
+       { "5111A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111A },
        { "2111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2111 },
        { "5112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112 },
        { "5112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112A },
+       { "5112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112B },
        { "2112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112 },
        { "2112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112A },
-       { "SChip",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_SC0 },
-       { "SChip",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_SC1 },
-       { "SChip",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_SC2 },
+       { "2112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112B },
+       { "2413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2413 },
+       { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
+       { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
+       { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
+       { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
        { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
        { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
 };
@@ -390,7 +397,11 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
        for (i = 0; i < ARRAY_SIZE(srev_names); i++) {
                if (srev_names[i].sr_type != type)
                        continue;
-               if ((val & 0xff) < srev_names[i + 1].sr_val) {
+
+               if ((val & 0xf0) == srev_names[i].sr_val)
+                       name = srev_names[i].sr_name;
+
+               if ((val & 0xff) == srev_names[i].sr_val) {
                        name = srev_names[i].sr_name;
                        break;
                }
@@ -536,7 +547,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
                goto err_ah;
 
        ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
-                       ath5k_chip_name(AR5K_VERSION_VER,sc->ah->ah_mac_srev),
+                       ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
                                        sc->ah->ah_mac_srev,
                                        sc->ah->ah_phy_revision);
 
index a28090be96036d44440925288e0516ea0222d71e..7adceb2c7fab50c33d4769b04364ec6655b4ad3e 100644 (file)
@@ -68,7 +68,7 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
        /*
         * It may take some time to disable the DMA receive unit
         */
-       for (i = 2000; i > 0 &&
+       for (i = 1000; i > 0 &&
                        (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
                        i--)
                udelay(10);
@@ -182,11 +182,10 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
  * have any pending frames. Returns -EBUSY if we still have pending frames,
  * -EINVAL if queue number is out of range.
  *
- * TODO: Test queue drain code
  */
 int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
 {
-       unsigned int i = 100;
+       unsigned int i = 40;
        u32 tx_queue, pending;
 
        ATH5K_TRACE(ah->ah_sc);
@@ -233,13 +232,53 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
                        udelay(100);
                } while (--i && pending);
 
+               /* For 2413+ order PCU to drop packets using
+                * QUIET mechanism */
+               if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&
+               pending){
+                       /* Set periodicity and duration */
+                       ath5k_hw_reg_write(ah,
+                               AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|
+                               AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR),
+                               AR5K_QUIET_CTL2);
+
+                       /* Enable quiet period for current TSF */
+                       ath5k_hw_reg_write(ah,
+                               AR5K_QUIET_CTL1_QT_EN |
+                               AR5K_REG_SM(ath5k_hw_reg_read(ah,
+                                               AR5K_TSF_L32_5211) >> 10,
+                                               AR5K_QUIET_CTL1_NEXT_QT_TSF),
+                               AR5K_QUIET_CTL1);
+
+                       /* Force channel idle high */
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
+                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
+
+                       /* Wait a while and disable mechanism */
+                       udelay(200);
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
+                                               AR5K_QUIET_CTL1_QT_EN);
+
+                       /* Re-check for pending frames */
+                       i = 40;
+                       do {
+                               pending = ath5k_hw_reg_read(ah,
+                                       AR5K_QUEUE_STATUS(queue)) &
+                                       AR5K_QCU_STS_FRMPENDCNT;
+                               udelay(100);
+                       } while (--i && pending);
+
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
+                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
+               }
+
                /* Clear register */
                ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
                if (pending)
                        return -EBUSY;
        }
 
-       /* TODO: Check for success else return error */
+       /* TODO: Check for success on 5210 else return error */
        return 0;
 }
 
@@ -415,7 +454,7 @@ done:
 bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
 {
        ATH5K_TRACE(ah->ah_sc);
-       return ath5k_hw_reg_read(ah, AR5K_INTPEND);
+       return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
 }
 
 /**
index c77cee2a558221db82f149dfed402f5431a59f0b..a47df9a24aa126783497eeb296edad22aa150d0e 100644 (file)
@@ -633,8 +633,20 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
  */
 void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
 {
+       u32 val;
+
        ATH5K_TRACE(ah->ah_sc);
-       AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);
+
+       val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
+
+       /*
+        * Each write to the RESET_TSF bit toggles a hardware internal
+        * signal to reset TSF, but if left high it will cause a TSF reset
+        * on the next chip reset as well.  Thus we always write the value
+        * twice to clear the signal.
+        */
+       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
+       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
 }
 
 /*
index 1ea8ed962d2673330f1e3101fe77e2f3f3eb6234..e43f6563e61a08ab6cbfcaaff1d455c6eb56e8f7 100644 (file)
@@ -2124,7 +2124,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
        beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
        ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
 
-       udelay(2300);
+       mdelay(2);
 
        /*
         * Set the channel (with AGC turned off)
index 2e20f7816ca768cb41851256c81de4784bde3aa5..01bf09176d23b79a993ed5daf4b33b30a22a9cc6 100644 (file)
@@ -375,7 +375,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
                case AR5K_TX_QUEUE_BEACON:
                        AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
                                AR5K_QCU_MISC_FRSHED_DBA_GT |
-                               AR5K_QCU_MISC_CBREXP_BCN |
+                               AR5K_QCU_MISC_CBREXP_BCN_DIS |
                                AR5K_QCU_MISC_BCN_ENABLE);
 
                        AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
@@ -395,8 +395,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
                case AR5K_TX_QUEUE_CAB:
                        AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
                                AR5K_QCU_MISC_FRSHED_DBA_GT |
-                               AR5K_QCU_MISC_CBREXP |
-                               AR5K_QCU_MISC_CBREXP_BCN);
+                               AR5K_QCU_MISC_CBREXP_DIS |
+                               AR5K_QCU_MISC_CBREXP_BCN_DIS);
 
                        AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
                                (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
@@ -405,7 +405,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
 
                case AR5K_TX_QUEUE_UAPSD:
                        AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_CBREXP);
+                               AR5K_QCU_MISC_CBREXP_DIS);
                        break;
 
                case AR5K_TX_QUEUE_DATA:
index a98832364448a764b47574a96b4613403944da0d..e557fe178bbf9401af6c7846118d0a7f46a16c84 100644 (file)
  *        http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf
  *
  * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf
+ *
+ * This file also contains register values found on a memory dump of
+ * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal
+ * released by Atheros and on various debug messages found on the net.
  */
 
 
 #define AR5K_ISR_RXPHY         0x00004000      /* PHY error */
 #define AR5K_ISR_RXKCM         0x00008000      /* RX Key cache miss */
 #define AR5K_ISR_SWBA          0x00010000      /* Software beacon alert */
-#define AR5K_ISR_BRSSI         0x00020000
+#define AR5K_ISR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
 #define AR5K_ISR_BMISS         0x00040000      /* Beacon missed */
 #define AR5K_ISR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
 #define AR5K_ISR_BNR           0x00100000      /* Beacon not ready [5211+] */
 #define AR5K_ISR_RXCHIRP       0x00200000      /* CHIRP Received [5212+] */
 #define AR5K_ISR_SSERR         0x00200000      /* Signaled System Error [5210] */
 #define AR5K_ISR_DPERR         0x00400000      /* Det par Error (?) [5210] */
-#define AR5K_ISR_TIM           0x00800000      /* [5210] */
-#define AR5K_ISR_BCNMISC       0x00800000      /* [5212+] */
-#define AR5K_ISR_GPIO          0x01000000      /* GPIO (rf kill)*/
-#define AR5K_ISR_QCBRORN       0x02000000      /* CBR overrun (?)  [5211+] */
-#define AR5K_ISR_QCBRURN       0x04000000      /* CBR underrun (?) [5211+] */
-#define AR5K_ISR_QTRIG         0x08000000      /* [5211+] */
+#define AR5K_ISR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
+#define AR5K_ISR_TIM           0x00800000      /* [5211+] */
+#define AR5K_ISR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
+                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
+#define AR5K_ISR_GPIO          0x01000000      /* GPIO (rf kill) */
+#define AR5K_ISR_QCBRORN       0x02000000      /* QCU CBR overrun [5211+] */
+#define AR5K_ISR_QCBRURN       0x04000000      /* QCU CBR underrun [5211+] */
+#define AR5K_ISR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
 
 /*
  * Secondary status registers [5211+] (0 - 4)
  *
- * I guess from the names that these give the status for each
- * queue, that's why only masks are defined here, haven't got
- * any info about them (couldn't find them anywhere in ar5k code).
+ * These give the status for each QCU, only QCUs 0-9 are
+ * represented.
  */
 #define AR5K_SISR0             0x0084                  /* Register Address [5211+] */
 #define AR5K_SISR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
+#define AR5K_SISR0_QCU_TXOK_S  0
 #define AR5K_SISR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
+#define AR5K_SISR0_QCU_TXDESC_S        16
 
 #define AR5K_SISR1             0x0088                  /* Register Address [5211+] */
 #define AR5K_SISR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
+#define AR5K_SISR1_QCU_TXERR_S 0
 #define AR5K_SISR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
+#define AR5K_SISR1_QCU_TXEOL_S 16
 
 #define AR5K_SISR2             0x008c                  /* Register Address [5211+] */
 #define AR5K_SISR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
+#define        AR5K_SISR2_QCU_TXURN_S  0
 #define        AR5K_SISR2_MCABT        0x00100000      /* Master Cycle Abort */
 #define        AR5K_SISR2_SSERR        0x00200000      /* Signaled System Error */
-#define        AR5K_SISR2_DPERR        0x00400000      /* Det par Error (?) */
+#define        AR5K_SISR2_DPERR        0x00400000      /* Bus parity error */
 #define        AR5K_SISR2_TIM          0x01000000      /* [5212+] */
 #define        AR5K_SISR2_CAB_END      0x02000000      /* [5212+] */
 #define        AR5K_SISR2_DTIM_SYNC    0x04000000      /* DTIM sync lost [5212+] */
 #define        AR5K_SISR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
 #define        AR5K_SISR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
 #define        AR5K_SISR2_DTIM         0x20000000      /* [5212+] */
+#define        AR5K_SISR2_TSFOOR       0x80000000      /* TSF OOR (?) */
 
 #define AR5K_SISR3             0x0090                  /* Register Address [5211+] */
 #define AR5K_SISR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
+#define AR5K_SISR3_QCBORN_S    0
 #define AR5K_SISR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
+#define AR5K_SISR3_QCBRURN_S   16
 
 #define AR5K_SISR4             0x0094                  /* Register Address [5211+] */
 #define AR5K_SISR4_QTRIG       0x000003ff      /* Mask for QTRIG */
+#define AR5K_SISR4_QTRIG_S     0
 
 /*
  * Shadow read-and-clear interrupt status registers [5211+]
 #define AR5K_IMR_RXPHY         0x00004000      /* PHY error*/
 #define AR5K_IMR_RXKCM         0x00008000      /* RX Key cache miss */
 #define AR5K_IMR_SWBA          0x00010000      /* Software beacon alert*/
-#define AR5K_IMR_BRSSI         0x00020000
+#define AR5K_IMR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
 #define AR5K_IMR_BMISS         0x00040000      /* Beacon missed*/
 #define AR5K_IMR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
 #define AR5K_IMR_BNR           0x00100000      /* Beacon not ready [5211+] */
 #define AR5K_IMR_RXCHIRP       0x00200000      /* CHIRP Received [5212+]*/
 #define AR5K_IMR_SSERR         0x00200000      /* Signaled System Error [5210] */
 #define AR5K_IMR_DPERR         0x00400000      /* Det par Error (?) [5210] */
+#define AR5K_IMR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
 #define AR5K_IMR_TIM           0x00800000      /* [5211+] */
-#define AR5K_IMR_BCNMISC       0x00800000      /* [5212+] */
+#define AR5K_IMR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
+                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
 #define AR5K_IMR_GPIO          0x01000000      /* GPIO (rf kill)*/
-#define AR5K_IMR_QCBRORN       0x02000000      /* CBR overrun (?) [5211+] */
-#define AR5K_IMR_QCBRURN       0x04000000      /* CBR underrun (?) [5211+] */
-#define AR5K_IMR_QTRIG         0x08000000      /* [5211+] */
+#define AR5K_IMR_QCBRORN       0x02000000      /* QCU CBR overrun (?) [5211+] */
+#define AR5K_IMR_QCBRURN       0x04000000      /* QCU CBR underrun (?) [5211+] */
+#define AR5K_IMR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
 
 /*
  * Secondary interrupt mask registers [5211+] (0 - 4)
 #define AR5K_SIMR2_QCU_TXURN_S 0
 #define        AR5K_SIMR2_MCABT        0x00100000      /* Master Cycle Abort */
 #define        AR5K_SIMR2_SSERR        0x00200000      /* Signaled System Error */
-#define        AR5K_SIMR2_DPERR        0x00400000      /* Det par Error (?) */
+#define        AR5K_SIMR2_DPERR        0x00400000      /* Bus parity error */
 #define        AR5K_SIMR2_TIM          0x01000000      /* [5212+] */
 #define        AR5K_SIMR2_CAB_END      0x02000000      /* [5212+] */
 #define        AR5K_SIMR2_DTIM_SYNC    0x04000000      /* DTIM Sync lost [5212+] */
 #define        AR5K_SIMR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
 #define        AR5K_SIMR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
 #define        AR5K_SIMR2_DTIM         0x20000000      /* [5212+] */
+#define        AR5K_SIMR2_TSFOOR       0x80000000      /* TSF OOR (?) */
 
 #define AR5K_SIMR3             0x00b0                  /* Register Address [5211+] */
 #define AR5K_SIMR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
 #define        AR5K_QCU_MISC_FRSHED_M          0x0000000f      /* Frame sheduling mask */
 #define        AR5K_QCU_MISC_FRSHED_ASAP               0       /* ASAP */
 #define        AR5K_QCU_MISC_FRSHED_CBR                1       /* Constant Bit Rate */
-#define        AR5K_QCU_MISC_FRSHED_DBA_GT             2       /* DMA Beacon alert gated (?) */
-#define        AR5K_QCU_MISC_FRSHED_TIM_GT             3       /* Time gated (?) */
-#define        AR5K_QCU_MISC_FRSHED_BCN_SENT_GT        4       /* Beacon sent gated (?) */
+#define        AR5K_QCU_MISC_FRSHED_DBA_GT             2       /* DMA Beacon alert gated */
+#define        AR5K_QCU_MISC_FRSHED_TIM_GT             3       /* TIMT gated */
+#define        AR5K_QCU_MISC_FRSHED_BCN_SENT_GT        4       /* Beacon sent gated */
 #define        AR5K_QCU_MISC_ONESHOT_ENABLE    0x00000010      /* Oneshot enable */
-#define        AR5K_QCU_MISC_CBREXP            0x00000020      /* CBR expired (normal queue) */
-#define        AR5K_QCU_MISC_CBREXP_BCN        0x00000040      /* CBR expired (beacon queue) */
+#define        AR5K_QCU_MISC_CBREXP_DIS        0x00000020      /* Disable CBR expired counter (normal queue) */
+#define        AR5K_QCU_MISC_CBREXP_BCN_DIS    0x00000040      /* Disable CBR expired counter (beacon queue) */
 #define        AR5K_QCU_MISC_BCN_ENABLE        0x00000080      /* Enable Beacon use */
-#define        AR5K_QCU_MISC_CBR_THRES_ENABLE  0x00000100      /* CBR threshold enabled */
-#define        AR5K_QCU_MISC_RDY_VEOL_POLICY   0x00000200      /* TXE reset when RDYTIME enalbed */
+#define        AR5K_QCU_MISC_CBR_THRES_ENABLE  0x00000100      /* CBR expired threshold enabled */
+#define        AR5K_QCU_MISC_RDY_VEOL_POLICY   0x00000200      /* TXE reset when RDYTIME expired or VEOL */
 #define        AR5K_QCU_MISC_CBR_RESET_CNT     0x00000400      /* CBR threshold (counter) reset */
 #define        AR5K_QCU_MISC_DCU_EARLY         0x00000800      /* DCU early termination */
 #define AR5K_QCU_MISC_DCU_CMP_EN       0x00001000      /* Enable frame compression */
 #define        AR5K_DCU_LCL_IFS_CW_MAX_S       10
 #define        AR5K_DCU_LCL_IFS_AIFS           0x0ff00000      /* Arbitrated Interframe Space */
 #define        AR5K_DCU_LCL_IFS_AIFS_S         20
+#define        AR5K_DCU_LCL_IFS_AIFS_MAX       0xfc            /* Anything above that can cause DCU to hang */
 #define        AR5K_QUEUE_DFS_LOCAL_IFS(_q)    AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q)
 
 /*
 /*
  * DCU misc registers [5211+]
  *
- * For some of the registers i couldn't find in the code
- * (only backoff stuff is there realy) i tried to match the
- * names with 802.11e parameters etc, so i guess VIRTCOL here
- * means Virtual Collision and HCFPOLL means Hybrid Coordination
- * factor Poll (CF- Poll). Arbiter lockout control controls the
+ * Note: Arbiter lockout control controls the
  * behaviour on low priority queues when we have multiple queues
  * with pending frames. Intra-frame lockout means we wait until
  * the queue's current frame transmits (with post frame backoff and bursting)
  * No lockout means there is no special handling.
  */
 #define AR5K_DCU_MISC_BASE             0x1100                  /* Register Address -Queue0 DCU_MISC */
-#define        AR5K_DCU_MISC_BACKOFF           0x000007ff      /* Mask for backoff threshold */
+#define        AR5K_DCU_MISC_BACKOFF           0x0000003f      /* Mask for backoff threshold */
+#define        AR5K_DCU_MISC_ETS_RTS_POL       0x00000040      /* End of transmission series
+                                                       station RTS/data failure count
+                                                       reset policy (?) */
+#define AR5K_DCU_MISC_ETS_CW_POL       0x00000080      /* End of transmission series
+                                                       CW reset policy */
+#define        AR5K_DCU_MISC_FRAG_WAIT         0x00000100      /* Wait for next fragment */
 #define AR5K_DCU_MISC_BACKOFF_FRAG     0x00000200      /* Enable backoff while bursting */
 #define        AR5K_DCU_MISC_HCFPOLL_ENABLE    0x00000800      /* CF - Poll enable */
 #define        AR5K_DCU_MISC_BACKOFF_PERSIST   0x00001000      /* Persistent backoff */
 #define        AR5K_DCU_MISC_FRMPRFTCH_ENABLE  0x00002000      /* Enable frame pre-fetch */
 #define        AR5K_DCU_MISC_VIRTCOL           0x0000c000      /* Mask for Virtual Collision (?) */
-#define        AR5K_DCU_MISC_VIRTCOL_NORMAL            0
-#define        AR5K_DCU_MISC_VIRTCOL_MODIFIED          1
-#define        AR5K_DCU_MISC_VIRTCOL_IGNORE            2
+#define        AR5K_DCU_MISC_VIRTCOL_NORMAL    0
+#define        AR5K_DCU_MISC_VIRTCOL_IGNORE    1
 #define        AR5K_DCU_MISC_BCN_ENABLE        0x00010000      /* Enable Beacon use */
 #define        AR5K_DCU_MISC_ARBLOCK_CTL       0x00060000      /* Arbiter lockout control mask */
 #define        AR5K_DCU_MISC_ARBLOCK_CTL_S     17
 #define        AR5K_DCU_GBL_IFS_MISC_TURBO_MODE        0x00000008      /* Turbo mode */
 #define        AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC     0x000003f0      /* SIFS Duration mask */
 #define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR          0x000ffc00      /* USEC Duration mask */
+#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S        10
 #define        AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY     0x00300000      /* DCU Arbiter delay mask */
-#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST     0x00400000      /* SIFC cnt reset policy (?) */
+#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST     0x00400000      /* SIFS cnt reset policy (?) */
 #define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST     0x00800000      /* AIFS cnt reset policy (?) */
 #define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS  0x01000000      /* Disable random LFSR slice */
 
 #define AR5K_RESET_CTL_MAC     0x00000004      /* MAC reset (PCU+Baseband ?) [5210] */
 #define AR5K_RESET_CTL_PHY     0x00000008      /* PHY reset [5210] */
 #define AR5K_RESET_CTL_PCI     0x00000010      /* PCI Core reset (interrupts etc) */
-#define AR5K_RESET_CTL_CHIP    (AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA |      \
-                               AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY)
 
 /*
  * Sleep control register
 #define AR5K_SLEEP_CTL_SLE_S           16
 #define AR5K_SLEEP_CTL_SLE_WAKE                0x00000000      /* Force chip awake */
 #define AR5K_SLEEP_CTL_SLE_SLP         0x00010000      /* Force chip sleep */
-#define AR5K_SLEEP_CTL_SLE_ALLOW       0x00020000
+#define AR5K_SLEEP_CTL_SLE_ALLOW       0x00020000      /* Normal sleep policy */
 #define AR5K_SLEEP_CTL_SLE_UNITS       0x00000008      /* [5211+] */
-/* more bits */
+#define AR5K_SLEEP_CTL_DUR_TIM_POL     0x00040000      /* Sleep duration timing policy */
+#define AR5K_SLEEP_CTL_DUR_WRITE_POL   0x00080000      /* Sleep duration write policy */
+#define AR5K_SLEEP_CTL_SLE_POL         0x00100000      /* Sleep policy mode */
 
 /*
  * Interrupt pending register
 
 /*
  * PCI configuration register
+ * TODO: Fix LED stuff
  */
 #define AR5K_PCICFG                    0x4010                  /* Register Address */
 #define AR5K_PCICFG_EEAE               0x00000001      /* Eeprom access enable [5210] */
-#define        AR5K_PCICFG_SLEEP_CLOCK_EN      0x00000002      /* Enable sleep clock (?) */
+#define AR5K_PCICFG_SLEEP_CLOCK_EN     0x00000002      /* Enable sleep clock */
 #define AR5K_PCICFG_CLKRUNEN           0x00000004      /* CLKRUN enable [5211+] */
 #define AR5K_PCICFG_EESIZE             0x00000018      /* Mask for EEPROM size [5211+] */
 #define AR5K_PCICFG_EESIZE_S           3
 #define AR5K_PCICFG_EESIZE_4K          0               /* 4K */
 #define AR5K_PCICFG_EESIZE_8K          1               /* 8K */
 #define AR5K_PCICFG_EESIZE_16K         2               /* 16K */
-#define AR5K_PCICFG_EESIZE_FAIL                3               /* Failed to get size (?) [5211+] */
+#define AR5K_PCICFG_EESIZE_FAIL                3               /* Failed to get size [5211+] */
 #define AR5K_PCICFG_LED                        0x00000060      /* Led status [5211+] */
 #define AR5K_PCICFG_LED_NONE           0x00000000      /* Default [5211+] */
 #define AR5K_PCICFG_LED_PEND           0x00000020      /* Scan / Auth pending */
 #define AR5K_PCICFG_LED_ASSOC          0x00000040      /* Associated */
 #define        AR5K_PCICFG_BUS_SEL             0x00000380      /* Mask for "bus select" [5211+] (?) */
-#define        AR5K_PCICFG_CBEFIX_DIS          0x00000400      /* Disable CBE fix (?) */
-#define AR5K_PCICFG_SL_INTEN           0x00000800      /* Enable interrupts when asleep (?) */
+#define AR5K_PCICFG_CBEFIX_DIS         0x00000400      /* Disable CBE fix */
+#define AR5K_PCICFG_SL_INTEN           0x00000800      /* Enable interrupts when asleep */
 #define AR5K_PCICFG_LED_BCTL           0x00001000      /* Led blink (?) [5210] */
-#define        AR5K_PCICFG_UNK                 0x00001000      /* Passed on some parts durring attach (?) */
-#define AR5K_PCICFG_SL_INPEN           0x00002000      /* Sleep even whith pending interrupts (?) */
+#define AR5K_PCICFG_RETRY_FIX          0x00001000      /* Enable pci core retry fix */
+#define AR5K_PCICFG_SL_INPEN           0x00002000      /* Sleep even whith pending interrupts*/
 #define AR5K_PCICFG_SPWR_DN            0x00010000      /* Mask for power status */
 #define AR5K_PCICFG_LEDMODE            0x000e0000      /* Ledmode [5211+] */
 #define AR5K_PCICFG_LEDMODE_PROP       0x00000000      /* Blink on standard traffic [5211+] */
 #define AR5K_PCICFG_LEDSTATE                           \
        (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE |        \
        AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW)
-#define        AR5K_PCICFG_SLEEP_CLOCK_RATE    0x03000000      /* Sleep clock rate (field) */
+#define        AR5K_PCICFG_SLEEP_CLOCK_RATE    0x03000000      /* Sleep clock rate */
+#define        AR5K_PCICFG_SLEEP_CLOCK_RATE_S  24
 
 /*
  * "General Purpose Input/Output" (GPIO) control register
 
 #define AR5K_GPIOCR            0x4014                          /* Register Address */
 #define AR5K_GPIOCR_INT_ENA    0x00008000              /* Enable GPIO interrupt */
-#define AR5K_GPIOCR_INT_SELL   0x00000000              /* Generate interrupt when pin is off (?) */
-#define AR5K_GPIOCR_INT_SELH   0x00010000              /* Generate interrupt when pin is on */
+#define AR5K_GPIOCR_INT_SELL   0x00000000              /* Generate interrupt when pin is low */
+#define AR5K_GPIOCR_INT_SELH   0x00010000              /* Generate interrupt when pin is high */
 #define AR5K_GPIOCR_IN(n)      (0 << ((n) * 2))        /* Mode 0 for pin n */
 #define AR5K_GPIOCR_OUT0(n)    (1 << ((n) * 2))        /* Mode 1 for pin n */
 #define AR5K_GPIOCR_OUT1(n)    (2 << ((n) * 2))        /* Mode 2 for pin n */
 #define AR5K_GPIODI    0x401c
 #define AR5K_GPIODI_M  0x0000002f
 
-
 /*
  * Silicon revision register
  */
 #define AR5K_SREV_VER          0x000000ff      /* Mask for version */
 #define AR5K_SREV_VER_S                4
 
+/*
+ * TXE write posting register
+ */
+#define        AR5K_TXEPOST    0x4028
+
+/*
+ * QCU sleep mask
+ */
+#define        AR5K_QCU_SLEEP_MASK     0x402c
+
+/* 0x4068 is compression buffer configuration
+ * register on 5414 and pm configuration register
+ * on 5424 and newer pci-e chips. */
+
+/*
+ * Compression buffer configuration
+ * register (enable/disable) [5414]
+ */
+#define AR5K_5414_CBCFG                0x4068
+#define AR5K_5414_CBCFG_BUF_DIS        0x10    /* Disable buffer */
+
+/*
+ * PCI-E Power managment configuration
+ * and status register [5424+]
+ */
+#define        AR5K_PCIE_PM_CTL                0x4068                  /* Register address */
+/* Only 5424 */
+#define        AR5K_PCIE_PM_CTL_L1_WHEN_D2     0x00000001      /* enable PCIe core enter L1
+                                                       when d2_sleep_en is asserted */
+#define        AR5K_PCIE_PM_CTL_L0_L0S_CLEAR   0x00000002      /* Clear L0 and L0S counters */
+#define        AR5K_PCIE_PM_CTL_L0_L0S_EN      0x00000004      /* Start L0 nd L0S counters */
+#define        AR5K_PCIE_PM_CTL_LDRESET_EN     0x00000008      /* Enable reset when link goes
+                                                       down */
+/* Wake On Wireless */
+#define        AR5K_PCIE_PM_CTL_PME_EN         0x00000010      /* PME Enable */
+#define        AR5K_PCIE_PM_CTL_AUX_PWR_DET    0x00000020      /* Aux power detect */
+#define        AR5K_PCIE_PM_CTL_PME_CLEAR      0x00000040      /* Clear PME */
+#define        AR5K_PCIE_PM_CTL_PSM_D0         0x00000080
+#define        AR5K_PCIE_PM_CTL_PSM_D1         0x00000100
+#define        AR5K_PCIE_PM_CTL_PSM_D2         0x00000200
+#define        AR5K_PCIE_PM_CTL_PSM_D3         0x00000400
+
+/*
+ * PCI-E Workaround enable register
+ */
+#define        AR5K_PCIE_WAEN  0x407c
 
+/*
+ * PCI-E Serializer/Desirializer
+ * registers
+ */
+#define        AR5K_PCIE_SERDES        0x4080
+#define        AR5K_PCIE_SERDES_RESET  0x4084
 
 /*====EEPROM REGISTERS====*/
 
  * EEPROM config register
  */
 #define AR5K_EEPROM_CFG                        0x6010                  /* Register Addres */
-#define AR5K_EEPROM_CFG_SIZE_OVR       0x00000001
+#define AR5K_EEPROM_CFG_SIZE           0x00000003              /* Size determination override */
+#define AR5K_EEPROM_CFG_SIZE_AUTO      0
+#define AR5K_EEPROM_CFG_SIZE_4KBIT     1
+#define AR5K_EEPROM_CFG_SIZE_8KBIT     2
+#define AR5K_EEPROM_CFG_SIZE_16KBIT    3
 #define AR5K_EEPROM_CFG_WR_WAIT_DIS    0x00000004      /* Disable write wait */
 #define AR5K_EEPROM_CFG_CLK_RATE       0x00000018      /* Clock rate */
-#define AR5K_EEPROM_CFG_PROT_KEY       0x00ffff00      /* Protectio key */
+#define AR5K_EEPROM_CFG_CLK_RATE_S             3
+#define AR5K_EEPROM_CFG_CLK_RATE_156KHZ        0
+#define AR5K_EEPROM_CFG_CLK_RATE_312KHZ        1
+#define AR5K_EEPROM_CFG_CLK_RATE_625KHZ        2
+#define AR5K_EEPROM_CFG_PROT_KEY       0x00ffff00      /* Protection key */
+#define AR5K_EEPROM_CFG_PROT_KEY_S     8
 #define AR5K_EEPROM_CFG_LIND_EN                0x01000000      /* Enable length indicator (?) */
 
 
+/*
+ * TODO: Wake On Wireless registers
+ * Range 0x7000 - 0x7ce0
+ */
+
 /*
  * Protocol Control Unit (PCU) registers
  */
 #define AR5K_STA_ID1_DESC_ANTENNA      0x00400000      /* Update antenna from descriptor */
 #define AR5K_STA_ID1_RTS_DEF_ANTENNA   0x00800000      /* Use default antenna for RTS */
 #define AR5K_STA_ID1_ACKCTS_6MB                0x01000000      /* Use 6Mbit/s for ACK/CTS */
-#define AR5K_STA_ID1_BASE_RATE_11B     0x02000000      /* Use 11b base rate (for ACK/CTS ?) [5211+] */
-#define AR5K_STA_ID1_SELF_GEN_SECTORE  0x04000000      /* Self generate sectore (?) */
+#define AR5K_STA_ID1_BASE_RATE_11B     0x02000000      /* Use 11b base rate for ACK/CTS [5211+] */
+#define AR5K_STA_ID1_SELFGEN_DEF_ANT   0x04000000      /* Use def. antenna for self generated frames */
 #define AR5K_STA_ID1_CRYPT_MIC_EN      0x08000000      /* Enable MIC */
-#define AR5K_STA_ID1_KEYSRCH_MODE      0x10000000      /* Keysearch mode (?) */
+#define AR5K_STA_ID1_KEYSRCH_MODE      0x10000000      /* Look up key when key id != 0 */
 #define AR5K_STA_ID1_PRESERVE_SEQ_NUM  0x20000000      /* Preserve sequence number */
+#define AR5K_STA_ID1_CBCIV_ENDIAN      0x40000000      /* ??? */
+#define AR5K_STA_ID1_KEYSRCH_MCAST     0x80000000      /* Do key cache search for mcast frames */
 
 /*
  * First BSSID register (MAC address, lower 32bits)
 #define AR5K_DIAG_SW_LOOP_BACK_5211    0x00000040
 #define AR5K_DIAG_SW_LOOP_BACK         (ah->ah_version == AR5K_AR5210 ? \
                                        AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
-#define AR5K_DIAG_SW_CORR_FCS_5210     0x00000100
+#define AR5K_DIAG_SW_CORR_FCS_5210     0x00000100      /* Corrupted FCS */
 #define AR5K_DIAG_SW_CORR_FCS_5211     0x00000080
 #define AR5K_DIAG_SW_CORR_FCS          (ah->ah_version == AR5K_AR5210 ? \
                                        AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
-#define AR5K_DIAG_SW_CHAN_INFO_5210    0x00000200
+#define AR5K_DIAG_SW_CHAN_INFO_5210    0x00000200      /* Dump channel info */
 #define AR5K_DIAG_SW_CHAN_INFO_5211    0x00000100
 #define AR5K_DIAG_SW_CHAN_INFO         (ah->ah_version == AR5K_AR5210 ? \
                                        AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
-#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211        0x00000200      /* Enable scrambler seed */
-#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210        0x00000400
+#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210        0x00000400      /* Enable fixed scrambler seed */
+#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211        0x00000200
 #define AR5K_DIAG_SW_EN_SCRAM_SEED     (ah->ah_version == AR5K_AR5210 ? \
                                        AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211)
 #define AR5K_DIAG_SW_ECO_ENABLE                0x00000400      /* [5211+] */
 #define AR5K_DIAG_SW_SCRAM_SEED_S      10
 #define AR5K_DIAG_SW_DIS_SEQ_INC       0x00040000      /* Disable seqnum increment (?)[5210] */
 #define AR5K_DIAG_SW_FRAME_NV0_5210    0x00080000
-#define AR5K_DIAG_SW_FRAME_NV0_5211    0x00020000
+#define AR5K_DIAG_SW_FRAME_NV0_5211    0x00020000      /* Accept frames of non-zero protocol number */
 #define        AR5K_DIAG_SW_FRAME_NV0          (ah->ah_version == AR5K_AR5210 ? \
                                        AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
-#define AR5K_DIAG_SW_OBSPT_M           0x000c0000
+#define AR5K_DIAG_SW_OBSPT_M           0x000c0000      /* Observation point select (?) */
 #define AR5K_DIAG_SW_OBSPT_S           18
-/* more bits */
+#define AR5K_DIAG_SW_RX_CLEAR_HIGH     0x0010000       /* Force RX Clear high */
+#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000       /* Ignore virtual carrier sense */
+#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH  0x0040000       /* Force channel idle high */
+#define AR5K_DIAG_SW_PHEAR_ME          0x0080000       /* ??? */
 
 /*
  * TSF (clock) register (lower 32 bits)
  *
  * XXX: PCDAC steps (0.5dbm) or DBM ?
  *
- * XXX: Mask changes for newer chips to 7f
- *      like tx power table ?
  */
 #define AR5K_TXPC                      0x80e8                  /* Register Address */
-#define AR5K_TXPC_ACK_M                        0x0000003f      /* Mask for ACK tx power */
+#define AR5K_TXPC_ACK_M                        0x0000003f      /* ACK tx power */
 #define AR5K_TXPC_ACK_S                        0
-#define AR5K_TXPC_CTS_M                        0x00003f00      /* Mask for CTS tx power */
+#define AR5K_TXPC_CTS_M                        0x00003f00      /* CTS tx power */
 #define AR5K_TXPC_CTS_S                        8
-#define AR5K_TXPC_CHIRP_M              0x003f0000      /* Mask for CHIRP tx power */
-#define AR5K_TXPC_CHIRP_S              22
+#define AR5K_TXPC_CHIRP_M              0x003f0000      /* CHIRP tx power */
+#define AR5K_TXPC_CHIRP_S              16
+#define AR5K_TXPC_DOPPLER              0x0f000000      /* Doppler chirp span (?) */
+#define AR5K_TXPC_DOPPLER_S            24
 
 /*
  * Profile count registers
 #define AR5K_PROFCNT_CYCLE             0x80f8  /* Cycle count (?) */
 
 /*
- * Quiet (period) control registers (?)
+ * Quiet period control registers
  */
 #define AR5K_QUIET_CTL1                        0x80fc                  /* Register Address */
-#define AR5K_QUIET_CTL1_NEXT_QT                0x0000ffff      /* Mask for next quiet (period?) (?) */
-#define AR5K_QUIET_CTL1_QT_EN          0x00010000      /* Enable quiet (period?) */
+#define AR5K_QUIET_CTL1_NEXT_QT_TSF    0x0000ffff      /* Next quiet period TSF (TU) */
+#define AR5K_QUIET_CTL1_NEXT_QT_TSF_S  0
+#define AR5K_QUIET_CTL1_QT_EN          0x00010000      /* Enable quiet period */
+#define AR5K_QUIET_CTL1_ACK_CTS_EN     0x00020000      /* Send ACK/CTS during quiet period */
+
 #define AR5K_QUIET_CTL2                        0x8100                  /* Register Address */
-#define AR5K_QUIET_CTL2_QT_PER         0x0000ffff      /* Mask for quiet period (?) */
-#define AR5K_QUIET_CTL2_QT_DUR         0xffff0000      /* Mask for quiet duration (?) */
+#define AR5K_QUIET_CTL2_QT_PER         0x0000ffff      /* Mask for quiet period periodicity */
+#define AR5K_QUIET_CTL2_QT_PER_S       0
+#define AR5K_QUIET_CTL2_QT_DUR         0xffff0000      /* Mask for quiet period duration */
+#define AR5K_QUIET_CTL2_QT_DUR_S       16
 
 /*
  * TSF parameter register
 #define AR5K_TSF_PARM_INC_S            0
 
 /*
- * QoS register (?)
+ * QoS NOACK policy
  */
-#define AR5K_QOS                       0x8108                  /* Register Address */
-#define AR5K_QOS_NOACK_2BIT_VALUES     0x00000000      /* (field) */
-#define AR5K_QOS_NOACK_BIT_OFFSET      0x00000020      /* (field) */
-#define AR5K_QOS_NOACK_BYTE_OFFSET     0x00000080      /* (field) */
+#define AR5K_QOS_NOACK                 0x8108                  /* Register Address */
+#define AR5K_QOS_NOACK_2BIT_VALUES     0x0000000f      /* ??? */
+#define AR5K_QOS_NOACK_2BIT_VALUES_S   0
+#define AR5K_QOS_NOACK_BIT_OFFSET      0x00000070      /* ??? */
+#define AR5K_QOS_NOACK_BIT_OFFSET_S    4
+#define AR5K_QOS_NOACK_BYTE_OFFSET     0x00000180      /* ??? */
+#define AR5K_QOS_NOACK_BYTE_OFFSET_S   8
 
 /*
  * PHY error filter register
 /*
  * MIC QoS control register (?)
  */
-#define        AR5K_MIC_QOS_CTL        0x8118                  /* Register Address */
-#define        AR5K_MIC_QOS_CTL_0      0x00000001      /* MIC QoS control 0 (?) */
-#define        AR5K_MIC_QOS_CTL_1      0x00000004      /* MIC QoS control 1 (?) */
-#define        AR5K_MIC_QOS_CTL_2      0x00000010      /* MIC QoS control 2 (?) */
-#define        AR5K_MIC_QOS_CTL_3      0x00000040      /* MIC QoS control 3 (?) */
-#define        AR5K_MIC_QOS_CTL_4      0x00000100      /* MIC QoS control 4 (?) */
-#define        AR5K_MIC_QOS_CTL_5      0x00000400      /* MIC QoS control 5 (?) */
-#define        AR5K_MIC_QOS_CTL_6      0x00001000      /* MIC QoS control 6 (?) */
-#define        AR5K_MIC_QOS_CTL_7      0x00004000      /* MIC QoS control 7 (?) */
-#define        AR5K_MIC_QOS_CTL_MQ_EN  0x00010000      /* Enable MIC QoS */
+#define        AR5K_MIC_QOS_CTL                0x8118                  /* Register Address */
+#define        AR5K_MIC_QOS_CTL_OFF(_n)        (1 << (_n * 2))
+#define        AR5K_MIC_QOS_CTL_MQ_EN          0x00010000      /* Enable MIC QoS */
 
 /*
  * MIC QoS select register (?)
  */
-#define        AR5K_MIC_QOS_SEL        0x811c
-#define        AR5K_MIC_QOS_SEL_0      0x00000001
-#define        AR5K_MIC_QOS_SEL_1      0x00000010
-#define        AR5K_MIC_QOS_SEL_2      0x00000100
-#define        AR5K_MIC_QOS_SEL_3      0x00001000
-#define        AR5K_MIC_QOS_SEL_4      0x00010000
-#define        AR5K_MIC_QOS_SEL_5      0x00100000
-#define        AR5K_MIC_QOS_SEL_6      0x01000000
-#define        AR5K_MIC_QOS_SEL_7      0x10000000
+#define        AR5K_MIC_QOS_SEL                0x811c
+#define        AR5K_MIC_QOS_SEL_OFF(_n)        (1 << (_n * 4))
 
 /*
  * Misc mode control register (?)
  */
 #define        AR5K_TSF_THRES                  0x813c
 
+/*
+ * TODO: Wake On Wireless registers
+ * Range: 0x8147 - 0x818c
+ */
+
 /*
  * Rate -> ACK SIFS mapping table (32 entries)
  */
  */
 #define        AR5K_PHY_TURBO                  0x9804                  /* Register Address */
 #define        AR5K_PHY_TURBO_MODE             0x00000001      /* Enable turbo mode */
-#define        AR5K_PHY_TURBO_SHORT            0x00000002      /* Short mode (20Mhz channels) (?) */
+#define        AR5K_PHY_TURBO_SHORT            0x00000002      /* Set short symbols to turbo mode */
+#define        AR5K_PHY_TURBO_MIMO             0x00000004      /* Set turbo for mimo mimo */
 
 /*
  * PHY agility command register
 #define        AR5K_PHY_TST1                   0x9808
 #define        AR5K_PHY_AGC_DISABLE            0x08000000      /* Disable AGC to A2 (?)*/
 #define        AR5K_PHY_TST1_TXHOLD            0x00003800      /* Set tx hold (?) */
+#define        AR5K_PHY_TST1_TXSRC_SRC         0x00000002      /* Used with bit 7 (?) */
+#define        AR5K_PHY_TST1_TXSRC_SRC_S       1
+#define        AR5K_PHY_TST1_TXSRC_ALT         0x00000080      /* Set input to tsdac (?) */
+#define        AR5K_PHY_TST1_TXSRC_ALT_S       7
+
 
 /*
  * PHY timing register 3 [5112+]
 
 /*
  * PHY RF control registers
- * (i think these are delay times,
- * these calibration values exist
- * in EEPROM)
  */
 #define AR5K_PHY_RF_CTL2               0x9824                  /* Register Address */
-#define        AR5K_PHY_RF_CTL2_TXF2TXD_START  0x0000000f      /* Mask for TX frame to TX d(esc?) start */
+#define        AR5K_PHY_RF_CTL2_TXF2TXD_START  0x0000000f      /* TX frame to TX data start */
+#define        AR5K_PHY_RF_CTL2_TXF2TXD_START_S        0
 
 #define AR5K_PHY_RF_CTL3               0x9828                  /* Register Address */
-#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON   0x0000000f      /* Mask for TX end to XLNA on */
+#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON   0x0000000f      /* TX end to XLNA on */
+#define        AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S  0
+
+#define        AR5K_PHY_ADC_CTL                        0x982c
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF          0x00000003
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S        0
+#define        AR5K_PHY_ADC_CTL_PWD_DAC_OFF            0x00002000
+#define        AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF       0x00004000
+#define        AR5K_PHY_ADC_CTL_PWD_ADC_OFF            0x00008000
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON           0x00030000
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S         16
 
 #define AR5K_PHY_RF_CTL4               0x9834                  /* Register Address */
 #define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON  0x00000001      /* TX frame to XPA A on (field) */
  * PHY settling register
  */
 #define AR5K_PHY_SETTLING              0x9844                  /* Register Address */
-#define        AR5K_PHY_SETTLING_AGC           0x0000007f      /* Mask for AGC settling time */
-#define        AR5K_PHY_SETTLING_SWITCH        0x00003f80      /* Mask for Switch settlig time */
+#define        AR5K_PHY_SETTLING_AGC           0x0000007f      /* AGC settling time */
+#define        AR5K_PHY_SETTLING_AGC_S         0
+#define        AR5K_PHY_SETTLING_SWITCH        0x00003f80      /* Switch settlig time */
+#define        AR5K_PHY_SETTLINK_SWITCH_S      7
 
 /*
  * PHY Gain registers
  */
 #define AR5K_PHY_GAIN                  0x9848                  /* Register Address */
-#define        AR5K_PHY_GAIN_TXRX_ATTEN        0x0003f000      /* Mask for TX-RX Attenuation */
+#define        AR5K_PHY_GAIN_TXRX_ATTEN        0x0003f000      /* TX-RX Attenuation */
+#define        AR5K_PHY_GAIN_TXRX_ATTEN_S      12
+#define        AR5K_PHY_GAIN_TXRX_RF_MAX       0x007c0000
+#define        AR5K_PHY_GAIN_TXRX_RF_MAX_S     18
 
 #define        AR5K_PHY_GAIN_OFFSET            0x984c                  /* Register Address */
 #define        AR5K_PHY_GAIN_OFFSET_RXTX_FLAG  0x00020000      /* RX-TX flag (?) */
  * (for more infos read ANI patent)
  */
 #define AR5K_PHY_DESIRED_SIZE          0x9850                  /* Register Address */
-#define        AR5K_PHY_DESIRED_SIZE_ADC       0x000000ff      /* Mask for ADC desired size */
-#define        AR5K_PHY_DESIRED_SIZE_PGA       0x0000ff00      /* Mask for PGA desired size */
-#define        AR5K_PHY_DESIRED_SIZE_TOT       0x0ff00000      /* Mask for Total desired size */
+#define        AR5K_PHY_DESIRED_SIZE_ADC       0x000000ff      /* ADC desired size */
+#define        AR5K_PHY_DESIRED_SIZE_ADC_S     0
+#define        AR5K_PHY_DESIRED_SIZE_PGA       0x0000ff00      /* PGA desired size */
+#define        AR5K_PHY_DESIRED_SIZE_PGA_S     8
+#define        AR5K_PHY_DESIRED_SIZE_TOT       0x0ff00000      /* Total desired size */
+#define        AR5K_PHY_DESIRED_SIZE_TOT_S     20
 
 /*
  * PHY signal register
  * (for more infos read ANI patent)
  */
 #define        AR5K_PHY_SIG                    0x9858                  /* Register Address */
-#define        AR5K_PHY_SIG_FIRSTEP            0x0003f000      /* Mask for FIRSTEP */
+#define        AR5K_PHY_SIG_FIRSTEP            0x0003f000      /* FIRSTEP */
 #define        AR5K_PHY_SIG_FIRSTEP_S          12
-#define        AR5K_PHY_SIG_FIRPWR             0x03fc0000      /* Mask for FIPWR */
+#define        AR5K_PHY_SIG_FIRPWR             0x03fc0000      /* FIPWR */
 #define        AR5K_PHY_SIG_FIRPWR_S           18
 
 /*
  * (for more infos read ANI patent)
  */
 #define        AR5K_PHY_AGCCOARSE              0x985c                  /* Register Address */
-#define        AR5K_PHY_AGCCOARSE_LO           0x00007f80      /* Mask for AGC Coarse low */
+#define        AR5K_PHY_AGCCOARSE_LO           0x00007f80      /* AGC Coarse low */
 #define        AR5K_PHY_AGCCOARSE_LO_S         7
-#define        AR5K_PHY_AGCCOARSE_HI           0x003f8000      /* Mask for AGC Coarse high */
+#define        AR5K_PHY_AGCCOARSE_HI           0x003f8000      /* AGC Coarse high */
 #define        AR5K_PHY_AGCCOARSE_HI_S         15
 
 /*
 #define        AR5K_PHY_AGCCTL                 0x9860                  /* Register address */
 #define        AR5K_PHY_AGCCTL_CAL             0x00000001      /* Enable PHY calibration */
 #define        AR5K_PHY_AGCCTL_NF              0x00000002      /* Enable Noise Floor calibration */
+#define        AR5K_PHY_AGCCTL_NF_EN           0x00008000      /* Enable nf calibration to happen (?) */
+#define        AR5K_PHY_AGCCTL_NF_NOUPDATE     0x00020000      /* Don't update nf automaticaly */
 
 /*
  * PHY noise floor status register
 #define AR5K_PHY_NF_RVAL(_n)           (((_n) >> 19) & AR5K_PHY_NF_M)
 #define AR5K_PHY_NF_AVAL(_n)           (-((_n) ^ AR5K_PHY_NF_M) + 1)
 #define AR5K_PHY_NF_SVAL(_n)           (((_n) & AR5K_PHY_NF_M) | (1 << 9))
-#define        AR5K_PHY_NF_THRESH62            0x00001000      /* Thresh62 -check ANI patent- (field) */
+#define        AR5K_PHY_NF_THRESH62            0x0007f000      /* Thresh62 -check ANI patent- (field) */
+#define        AR5K_PHY_NF_THRESH62_S          12
+#define        AR5K_PHY_NF_MINCCA_PWR          0x0ff80000      /* ??? */
+#define        AR5K_PHY_NF_MINCCA_PWR_S        19
 
 /*
  * PHY ADC saturation register [5110]
  */
 #define AR5K_PHY_SCR                   0x9870
 #define AR5K_PHY_SCR_32MHZ             0x0000001f
+
 #define AR5K_PHY_SLMT                  0x9874
 #define AR5K_PHY_SLMT_32MHZ            0x0000007f
+
 #define AR5K_PHY_SCAL                  0x9878
 #define AR5K_PHY_SCAL_32MHZ            0x0000000e
 
+
 /*
  * PHY PLL (Phase Locked Loop) control register
  */
 #define        AR5K_PHY_PLL                    0x987c
-#define        AR5K_PHY_PLL_20MHZ              0x13    /* For half rate (?) [5111+] */
-#define        AR5K_PHY_PLL_40MHZ_5211         0x18    /* For 802.11a */
+#define        AR5K_PHY_PLL_20MHZ              0x00000013      /* For half rate (?) */
+/* 40MHz -> 5GHz band */
+#define        AR5K_PHY_PLL_40MHZ_5211         0x00000018
 #define        AR5K_PHY_PLL_40MHZ_5212         0x000000aa
+#define        AR5K_PHY_PLL_40MHZ_5413         0x00000004
 #define        AR5K_PHY_PLL_40MHZ              (ah->ah_version == AR5K_AR5211 ? \
                                        AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212)
-#define        AR5K_PHY_PLL_44MHZ_5211         0x19    /* For 802.11b/g */
+/* 44MHz -> 2.4GHz band */
+#define        AR5K_PHY_PLL_44MHZ_5211         0x00000019
 #define        AR5K_PHY_PLL_44MHZ_5212         0x000000ab
 #define        AR5K_PHY_PLL_44MHZ              (ah->ah_version == AR5K_AR5211 ? \
                                        AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212)
+
 #define AR5K_PHY_PLL_RF5111            0x00000000
 #define AR5K_PHY_PLL_RF5112            0x00000040
 #define        AR5K_PHY_PLL_HALF_RATE          0x00000100
 #define AR5K_PHY_RFSTG                 0x98d4
 #define AR5K_PHY_RFSTG_DISABLE         0x00000021
 
+/*
+ * BIN masks (?)
+ */
+#define        AR5K_PHY_BIN_MASK_1     0x9900
+#define        AR5K_PHY_BIN_MASK_2     0x9904
+#define        AR5K_PHY_BIN_MASK_3     0x9908
+
+#define        AR5K_PHY_BIN_MASK_CTL           0x990c
+#define        AR5K_PHY_BIN_MASK_CTL_MASK_4    0x00003fff
+#define        AR5K_PHY_BIN_MASK_CTL_MASK_4_S  0
+#define        AR5K_PHY_BIN_MASK_CTL_RATE      0xff000000
+#define        AR5K_PHY_BIN_MASK_CTL_RATE_S    24
+
 /*
  * PHY Antenna control register
  */
 #define        AR5K_PHY_OFDM_SELFCORR                  0x9924                  /* Register Address */
 #define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN    0x00000001      /* Enable cyclic RSSI thr 1 */
 #define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1       0x000000fe      /* Mask for Cyclic RSSI threshold 1 */
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S     0
 #define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3       0x00000100      /* Cyclic RSSI threshold 3 (field) (?) */
 #define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN    0x00008000      /* Enable 1A RSSI threshold (?) */
 #define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR       0x00010000      /* 1A RSSI threshold (field) (?) */
 #define        AR5K_PHY_PAPD_PROBE_INI_5111    0x00004883      /* [5212+] */
 #define        AR5K_PHY_PAPD_PROBE_INI_5112    0x00004882      /* [5212+] */
 
-
 /*
  * PHY TX rate power registers [5112+]
  */
 #define        AR5K_PHY_FRAME_CTL_TX_CLIP      0x00000038      /* Mask for tx clip (?) */
 #define        AR5K_PHY_FRAME_CTL_TX_CLIP_S    3
 #define        AR5K_PHY_FRAME_CTL_PREP_CHINFO  0x00010000      /* Prepend chan info */
+#define        AR5K_PHY_FRAME_CTL_EMU          0x80000000
+#define        AR5K_PHY_FRAME_CTL_EMU_S        31
 /*---[5110/5111]---*/
 #define        AR5K_PHY_FRAME_CTL_TIMING_ERR   0x01000000      /* PHY timing error */
 #define        AR5K_PHY_FRAME_CTL_PARITY_ERR   0x02000000      /* Parity error */
  * PHY radar detection register [5111+]
  */
 #define        AR5K_PHY_RADAR                  0x9954
-
-/* Radar enable                        ........ ........ ........ .......1 */
 #define        AR5K_PHY_RADAR_ENABLE           0x00000001
-#define        AR5K_PHY_RADAR_DISABLE          0x00000000
-#define        AR5K_PHY_RADAR_ENABLE_S         0
-
-/* This is the value found on the card  .1.111.1 .1.1.... 111....1 1...1...
-at power on. */
-#define        AR5K_PHY_RADAR_PWONDEF_AR5213   0x5d50e188
-
-/* This is the value found on the card         .1.1.111 ..11...1 .1...1.1 1...11.1
-after DFS is enabled */
-#define        AR5K_PHY_RADAR_ENABLED_AR5213   0x5731458d
-
-/* Finite Impulse Response (FIR) filter .1111111 ........ ........ ........
- * power out threshold.
- * 7-bits, standard power range {0..127} in 1/2 dBm units. */
-#define AR5K_PHY_RADAR_FIRPWROUTTHR            0x7f000000
-#define AR5K_PHY_RADAR_FIRPWROUTTHR_S  24
-
-/* Radar RSSI/SNR threshold.           ........ 111111.. ........ ........
- * 6-bits, dBm range {0..63} in dBm units. */
-#define AR5K_PHY_RADAR_RADARRSSITHR            0x00fc0000
-#define AR5K_PHY_RADAR_RADARRSSITHR_S  18
-
-/* Pulse height threshold              ........ ......11 1111.... ........
- * 6-bits, dBm range {0..63} in dBm units. */
-#define AR5K_PHY_RADAR_PULSEHEIGHTTHR   0x0003f000
-#define AR5K_PHY_RADAR_PULSEHEIGHTTHR_S        12
-
-/* Pulse RSSI/SNR threshold            ........ ........ ....1111 11......
- * 6-bits, dBm range {0..63} in dBm units. */
-#define AR5K_PHY_RADAR_PULSERSSITHR            0x00000fc0
-#define AR5K_PHY_RADAR_PULSERSSITHR_S  6
-
-/* Inband threshold                    ........ ........ ........ ..11111.
- * 5-bits, units unknown {0..31} (? MHz ?) */
-#define AR5K_PHY_RADAR_INBANDTHR       0x0000003e
+#define        AR5K_PHY_RADAR_DISABLE          0x00000000
+#define AR5K_PHY_RADAR_INBANDTHR       0x0000003e      /* Inband threshold
+                                                       5-bits, units unknown {0..31}
+                                                       (? MHz ?) */
 #define AR5K_PHY_RADAR_INBANDTHR_S     1
 
+#define AR5K_PHY_RADAR_PRSSI_THR       0x00000fc0      /* Pulse RSSI/SNR threshold
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_PRSSI_THR_S     6
+
+#define AR5K_PHY_RADAR_PHEIGHT_THR     0x0003f000      /* Pulse height threshold
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_PHEIGHT_THR_S   12
+
+#define AR5K_PHY_RADAR_RSSI_THR        0x00fc0000      /* Radar RSSI/SNR threshold.
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_RSSI_THR_S      18
+
+#define AR5K_PHY_RADAR_FIRPWR_THR      0x7f000000      /* Finite Impulse Response
+                                                       filter power out threshold.
+                                                       7-bits, standard power range
+                                                       {0..127} in 1/2 dBm units. */
+#define AR5K_PHY_RADAR_FIRPWR_THRS     24
+
 /*
- * PHY antenna switch table registers [5110]
+ * PHY antenna switch table registers
  */
 #define AR5K_PHY_ANT_SWITCH_TABLE_0    0x9960
 #define AR5K_PHY_ANT_SWITCH_TABLE_1    0x9964
@@ -2210,25 +2338,65 @@ after DFS is enabled */
 #define AR5K_PHY_NFTHRES               0x9968
 
 /*
- * PHY clock sleep registers [5112+]
+ * Sigma Delta register (?) [5213]
  */
-#define AR5K_PHY_SCLOCK                        0x99f0
-#define AR5K_PHY_SCLOCK_32MHZ          0x0000000c
-#define AR5K_PHY_SDELAY                        0x99f4
-#define AR5K_PHY_SDELAY_32MHZ          0x000000ff
-#define AR5K_PHY_SPENDING              0x99f8
-#define        AR5K_PHY_SPENDING_14            0x00000014
-#define        AR5K_PHY_SPENDING_18            0x00000018
-#define AR5K_PHY_SPENDING_RF5111       0x00000018
-#define AR5K_PHY_SPENDING_RF5112       0x00000014
-/* #define AR5K_PHY_SPENDING_RF5112A   0x0000000e */
-/* #define AR5K_PHY_SPENDING_RF5424    0x00000012 */
-#define        AR5K_PHY_SPENDING_RF5413        0x00000014
-#define        AR5K_PHY_SPENDING_RF2413        0x00000014
-#define AR5K_PHY_SPENDING_RF2425       0x00000018
+#define AR5K_PHY_SIGMA_DELTA           0x996C
+#define AR5K_PHY_SIGMA_DELTA_ADC_SEL   0x00000003
+#define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0
+#define AR5K_PHY_SIGMA_DELTA_FILT2     0x000000f8
+#define AR5K_PHY_SIGMA_DELTA_FILT2_S   3
+#define AR5K_PHY_SIGMA_DELTA_FILT1     0x00001f00
+#define AR5K_PHY_SIGMA_DELTA_FILT1_S   8
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP  0x01ff3000
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S        13
+
+/*
+ * RF restart register [5112+] (?)
+ */
+#define AR5K_PHY_RESTART               0x9970          /* restart */
+#define AR5K_PHY_RESTART_DIV_GC                0x001c0000      /* Fast diversity gc_limit (?) */
+#define AR5K_PHY_RESTART_DIV_GC_S      18
+
+/*
+ * RF Bus access request register (for synth-oly channel switching)
+ */
+#define AR5K_PHY_RFBUS_REQ             0x997C
+#define AR5K_PHY_RFBUS_REQ_REQUEST     0x00000001
 
 /*
- * Misc PHY/radio registers [5110 - 5111]
+ * Spur mitigation masks (?)
+ */
+#define AR5K_PHY_TIMING_7              0x9980
+#define AR5K_PHY_TIMING_8              0x9984
+#define AR5K_PHY_TIMING_8_PILOT_MASK_2         0x000fffff
+#define AR5K_PHY_TIMING_8_PILOT_MASK_2_S       0
+
+#define AR5K_PHY_BIN_MASK2_1           0x9988
+#define AR5K_PHY_BIN_MASK2_2           0x998c
+#define AR5K_PHY_BIN_MASK2_3           0x9990
+
+#define AR5K_PHY_BIN_MASK2_4           0x9994
+#define AR5K_PHY_BIN_MASK2_4_MASK_4    0x00003fff
+#define AR5K_PHY_BIN_MASK2_4_MASK_4_S  0
+
+#define AR_PHY_TIMING_9                        0x9998
+#define AR_PHY_TIMING_10               0x999c
+#define AR_PHY_TIMING_10_PILOT_MASK_2  0x000fffff
+#define AR_PHY_TIMING_10_PILOT_MASK_2_S        0
+
+/*
+ * Spur mitigation control
+ */
+#define AR_PHY_TIMING_11                       0x99a0          /* Register address */
+#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE      0x000fffff      /* Spur delta phase */
+#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE_S    0
+#define AR_PHY_TIMING_11_SPUR_FREQ_SD          0x3ff00000      /* Freq sigma delta */
+#define AR_PHY_TIMING_11_SPUR_FREQ_SD_S        20
+#define AR_PHY_TIMING_11_USE_SPUR_IN_AGC       0x40000000      /* Spur filter in AGC detector */
+#define AR_PHY_TIMING_11_USE_SPUR_IN_SELFCOR   0x80000000      /* Spur filter in OFDM self correlator */
+
+/*
+ * Gain tables
  */
 #define        AR5K_BB_GAIN_BASE               0x9b00  /* BaseBand Amplifier Gain table base address */
 #define AR5K_BB_GAIN(_n)               (AR5K_BB_GAIN_BASE + ((_n) << 2))
@@ -2248,9 +2416,10 @@ after DFS is enabled */
 #define        AR5K_PHY_CURRENT_RSSI   0x9c1c
 
 /*
- * PHY RF Bus grant register (?)
+ * PHY RF Bus grant register
  */
 #define        AR5K_PHY_RFBUS_GRANT    0x9c20
+#define        AR5K_PHY_RFBUS_GRANT_OK 0x00000001
 
 /*
  * PHY ADC test register
@@ -2293,6 +2462,31 @@ after DFS is enabled */
 #define        AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004
 #define        AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008
 
+/*
+ * Heavy clip enable register
+ */
+#define        AR5K_PHY_HEAVY_CLIP_ENABLE      0x99e0
+
+/*
+ * PHY clock sleep registers [5112+]
+ */
+#define AR5K_PHY_SCLOCK                        0x99f0
+#define AR5K_PHY_SCLOCK_32MHZ          0x0000000c
+#define AR5K_PHY_SDELAY                        0x99f4
+#define AR5K_PHY_SDELAY_32MHZ          0x000000ff
+#define AR5K_PHY_SPENDING              0x99f8
+#define AR5K_PHY_SPENDING_14           0x00000014
+#define AR5K_PHY_SPENDING_18           0x00000018
+#define AR5K_PHY_SPENDING_RF5111       0x00000018
+#define AR5K_PHY_SPENDING_RF5112       0x00000014
+/* #define AR5K_PHY_SPENDING_RF5112A   0x0000000e */
+/* #define AR5K_PHY_SPENDING_RF5424    0x00000012 */
+#define AR5K_PHY_SPENDING_RF5413       0x00000018
+#define AR5K_PHY_SPENDING_RF2413       0x00000018
+#define AR5K_PHY_SPENDING_RF2316       0x00000018
+#define AR5K_PHY_SPENDING_RF2317       0x00000018
+#define AR5K_PHY_SPENDING_RF2425       0x00000014
+
 /*
  * PHY PAPD I (power?) table (?)
  * (92! entries)
@@ -2344,10 +2538,47 @@ after DFS is enabled */
 #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR    0x0000000f
 #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S  0
 
+/* Same address is used for antenna diversity activation */
+#define        AR5K_PHY_FAST_ANT_DIV           0xa208
+#define        AR5K_PHY_FAST_ANT_DIV_EN        0x00002000
+
 /*
  * PHY 2GHz gain register [5111+]
  */
-#define        AR5K_PHY_GAIN_2GHZ              0xa20c
-#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX  0x00fc0000
+#define        AR5K_PHY_GAIN_2GHZ                      0xa20c
+#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX          0x00fc0000
 #define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S        18
-#define        AR5K_PHY_GAIN_2GHZ_INI_5111     0x6480416c
+#define        AR5K_PHY_GAIN_2GHZ_INI_5111             0x6480416c
+
+#define        AR5K_PHY_CCK_RX_CTL_4                   0xa21c
+#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT    0x01f80000
+#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S  19
+
+#define        AR5K_PHY_DAG_CCK_CTL                    0xa228
+#define        AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR        0x00000200
+#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR           0x0001fc00
+#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S         10
+
+#define        AR5K_PHY_FAST_ADC       0xa24c
+
+#define        AR5K_PHY_BLUETOOTH      0xa254
+
+/*
+ * Transmit Power Control register
+ * [2413+]
+ */
+#define        AR5K_PHY_TPC_RG1                0xa258
+#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN    0x0000c000
+#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S  14
+
+#define        AR5K_PHY_TPC_RG5                        0xa26C
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP        0x0000000F
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S      0
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1     0x000003F0
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S   4
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2     0x0000FC00
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S   10
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3     0x003F0000
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S   16
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4     0x0FC00000
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S   22
index f5c3de890cdbfb6e927ff9b6e871af8852a88d84..8f1886834e61fba8fe2bd5a7554b978b68717dd0 100644 (file)
@@ -173,8 +173,10 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
        udelay(15);
 
        if (ah->ah_version == AR5K_AR5210) {
-               val &= AR5K_RESET_CTL_CHIP;
-               mask &= AR5K_RESET_CTL_CHIP;
+               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
        } else {
                val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
                mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
@@ -361,16 +363,20 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
        bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
 
        /* Reset chipset */
-       ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
-               AR5K_RESET_CTL_BASEBAND | bus_flags);
+       if (ah->ah_version == AR5K_AR5210) {
+               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+                       AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+                       AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+                       mdelay(2);
+       } else {
+               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+                       AR5K_RESET_CTL_BASEBAND | bus_flags);
+       }
        if (ret) {
                ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
                return -EIO;
        }
 
-       if (ah->ah_version == AR5K_AR5210)
-               udelay(2300);
-
        /* ...wakeup again!*/
        ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
        if (ret) {
@@ -537,13 +543,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
                        ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
 
                        if (channel->hw_value == CHANNEL_G)
-                               if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
+                               if (ah->ah_mac_srev < AR5K_SREV_AR2413)
                                        ath5k_hw_reg_write(ah, 0x00f80d80,
                                                                0x994c);
-                               else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
+                               else if (ah->ah_mac_srev < AR5K_SREV_AR5424)
                                        ath5k_hw_reg_write(ah, 0x00380140,
                                                                0x994c);
-                               else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
+                               else if (ah->ah_mac_srev < AR5K_SREV_AR2425)
                                        ath5k_hw_reg_write(ah, 0x00fc0ec0,
                                                                0x994c);
                                else /* 2425 */
@@ -909,7 +915,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
                ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
                ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
                ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
-               if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
+               if (ah->ah_mac_srev >= AR5K_SREV_AR2413)
                        ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
        }
 
index c43fd58611636f96eb07ece52a0e7794d4b0fc3d..eedb465d25d330d4b8de9d42839367a97a1141f2 100644 (file)
@@ -16,7 +16,6 @@
 
  /* Implementation of beacon processing. */
 
-#include <asm/unaligned.h>
 #include "core.h"
 
 /*
@@ -26,7 +25,6 @@
  *  the operating mode of the station (AP or AdHoc).  Parameters are AIFS
  *  settings and channel width min/max
 */
-
 static int ath_beaconq_config(struct ath_softc *sc)
 {
        struct ath_hal *ah = sc->sc_ah;
@@ -63,19 +61,18 @@ static int ath_beaconq_config(struct ath_softc *sc)
  *  up all required antenna switch parameters, rate codes, and channel flags.
  *  Beacons are always sent out at the lowest rate, and are not retried.
 */
-
 static void ath_beacon_setup(struct ath_softc *sc,
-       struct ath_vap *avp, struct ath_buf *bf)
+                            struct ath_vap *avp, struct ath_buf *bf)
 {
        struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
        struct ath_hal *ah = sc->sc_ah;
        struct ath_desc *ds;
-       int flags, antenna;
+       struct ath9k_11n_rate_series series[4];
        const struct ath9k_rate_table *rt;
+       int flags, antenna;
        u8 rix, rate;
        int ctsrate = 0;
        int ctsduration = 0;
-       struct ath9k_11n_rate_series  series[4];
 
        DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n",
                __func__, skb, skb->len);
@@ -115,20 +112,21 @@ static void ath_beacon_setup(struct ath_softc *sc,
                rate |= rt->info[rix].shortPreamble;
 
        ath9k_hw_set11n_txdesc(ah, ds,
-                              skb->len + FCS_LEN, /* frame length */
-                              ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */
+                              skb->len + FCS_LEN,     /* frame length */
+                              ATH9K_PKT_TYPE_BEACON,  /* Atheros packet type */
                               avp->av_btxctl.txpower, /* txpower XXX */
-                              ATH9K_TXKEYIX_INVALID, /* no encryption */
-                              ATH9K_KEY_TYPE_CLEAR, /* no encryption */
-                              flags /* no ack, veol for beacons */
+                              ATH9K_TXKEYIX_INVALID,  /* no encryption */
+                              ATH9K_KEY_TYPE_CLEAR,   /* no encryption */
+                              flags                   /* no ack,
+                                                         veol for beacons */
                );
 
        /* NB: beacon's BufLen must be a multiple of 4 bytes */
        ath9k_hw_filltxdesc(ah, ds,
                            roundup(skb->len, 4), /* buffer length */
-                           true, /* first segment */
-                           true, /* last segment */
-                           ds /* first descriptor */
+                           true,                 /* first segment */
+                           true,                 /* last segment */
+                           ds                    /* first descriptor */
                );
 
        memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
@@ -153,22 +151,23 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
        struct ath_buf *bf;
        struct ath_vap *avp;
        struct sk_buff *skb;
-       int cabq_depth;
        struct ath_txq *cabq;
        struct ieee80211_tx_info *info;
+       int cabq_depth;
+
        avp = sc->sc_vaps[if_id];
+       ASSERT(avp);
 
        cabq = sc->sc_cabq;
 
-       ASSERT(avp);
-
        if (avp->av_bcbuf == NULL) {
                DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
                        __func__, avp, avp->av_bcbuf);
                return NULL;
        }
+
        bf = avp->av_bcbuf;
-       skb = (struct sk_buff *) bf->bf_mpdu;
+       skb = (struct sk_buff *)bf->bf_mpdu;
        if (skb) {
                pci_unmap_single(sc->pdev, bf->bf_dmacontext,
                                 skb_end_pointer(skb) - skb->head,
@@ -179,17 +178,19 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
        bf->bf_mpdu = skb;
        if (skb == NULL)
                return NULL;
+
        info = IEEE80211_SKB_CB(skb);
        if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
                /*
                 * TODO: make sure the seq# gets assigned properly (vs. other
                 * TX frames)
                 */
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
                sc->seq_no += 0x10;
                hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
                hdr->seq_ctrl |= cpu_to_le16(sc->seq_no);
        }
+
        bf->bf_buf_addr = bf->bf_dmacontext =
                pci_map_single(sc->pdev, skb->data,
                               skb_end_pointer(skb) - skb->head,
@@ -241,7 +242,6 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
  * Startup beacon transmission for adhoc mode when they are sent entirely
  * by the hardware using the self-linked descriptor + veol trick.
 */
-
 static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
 {
        struct ath_hal *ah = sc->sc_ah;
@@ -278,7 +278,6 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
  *  min/max, and enable aifs). The info structure does not need to be
  *  persistant.
 */
-
 int ath_beaconq_setup(struct ath_hal *ah)
 {
        struct ath9k_tx_queue_info qi;
@@ -299,26 +298,24 @@ int ath_beaconq_setup(struct ath_hal *ah)
  *  the ATH interface.  This routine also calculates the beacon "slot" for
  *  staggared beacons in the mBSSID case.
 */
-
 int ath_beacon_alloc(struct ath_softc *sc, int if_id)
 {
        struct ath_vap *avp;
-       struct ieee80211_hdr *wh;
+       struct ieee80211_hdr *hdr;
        struct ath_buf *bf;
        struct sk_buff *skb;
+       __le64 tstamp;
 
        avp = sc->sc_vaps[if_id];
        ASSERT(avp);
 
        /* Allocate a beacon descriptor if we haven't done so. */
        if (!avp->av_bcbuf) {
-               /*
-                * Allocate beacon state for hostap/ibss.  We know
-                * a buffer is available.
-                */
+               /* Allocate beacon state for hostap/ibss.  We know
+                * a buffer is available. */
 
                avp->av_bcbuf = list_first_entry(&sc->sc_bbuf,
-                               struct ath_buf, list);
+                                                struct ath_buf, list);
                list_del(&avp->av_bcbuf->list);
 
                if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP ||
@@ -362,9 +359,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
        }
 
        /*
-        * NB: the beacon data buffer must be 32-bit aligned;
-        * we assume the wbuf routines will return us something
-        * with this alignment (perhaps should assert).
+        * NB: the beacon data buffer must be 32-bit aligned.
         * FIXME: Fill avp->av_btxctl.txpower and
         * avp->av_btxctl.shortPreamble
         */
@@ -375,6 +370,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
                return -ENOMEM;
        }
 
+       tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+       sc->bc_tstamp = le64_to_cpu(tstamp);
+
        /*
         * Calculate a TSF adjustment factor required for
         * staggered beacons.  Note that we assume the format
@@ -408,8 +406,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
                        __func__, "stagger",
                        avp->av_bslot, intval, (unsigned long long)tsfadjust);
 
-               wh = (struct ieee80211_hdr *)skb->data;
-               memcpy(&wh[1], &val, sizeof(val));
+               hdr = (struct ieee80211_hdr *)skb->data;
+               memcpy(&hdr[1], &val, sizeof(val));
        }
 
        bf->bf_buf_addr = bf->bf_dmacontext =
@@ -425,9 +423,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id)
  *  Reclaim beacon resources and return buffer to the pool.
  *
  *  Checks the VAP to put the beacon frame buffer back to the ATH object
- *  queue, and de-allocates any wbuf frames that were sent as CAB traffic.
+ *  queue, and de-allocates any skbs that were sent as CAB traffic.
 */
-
 void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
 {
        if (avp->av_bcbuf != NULL) {
@@ -459,10 +456,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
  * Transmit one or more beacon frames at SWBA.  Dynamic updates to the frame
  * contents are done as needed and the slot time is also adjusted based on
  * current state.
- *
- * This tasklet is not scheduled, it's called in ISR context.
 */
-
 void ath9k_beacon_tasklet(unsigned long data)
 {
        struct ath_softc *sc = (struct ath_softc *)data;
@@ -490,6 +484,8 @@ void ath9k_beacon_tasklet(unsigned long data)
         * and wait for the next.  Missed beacons indicate
         * a problem and should not occur.  If we miss too
         * many consecutive beacons reset the device.
+        *
+        * FIXME: Clean up this mess !!
         */
        if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) {
                sc->sc_bmisscount++;
@@ -505,19 +501,16 @@ void ath9k_beacon_tasklet(unsigned long data)
                                        __func__, sc->sc_bmisscount);
                                if (show_cycles) {
                                        /*
-                                        * Display cycle counter stats
-                                        * from HW to aide in debug of
-                                        * stickiness.
+                                        * Display cycle counter stats from HW
+                                        * to aide in debug of stickiness.
                                         */
-                                       DPRINTF(sc,
-                                               ATH_DBG_BEACON,
+                                       DPRINTF(sc, ATH_DBG_BEACON,
                                                "%s: busy times: rx_clear=%d, "
                                                "rx_frame=%d, tx_frame=%d\n",
                                                __func__, rx_clear, rx_frame,
                                                tx_frame);
                                } else {
-                                       DPRINTF(sc,
-                                               ATH_DBG_BEACON,
+                                       DPRINTF(sc, ATH_DBG_BEACON,
                                                "%s: unable to obtain "
                                                "busy times\n", __func__);
                                }
@@ -529,8 +522,7 @@ void ath9k_beacon_tasklet(unsigned long data)
                } else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
                        if (sc->sc_flags & SC_OP_NO_RESET) {
                                if (sc->sc_bmisscount == BSTUCK_THRESH) {
-                                       DPRINTF(sc,
-                                               ATH_DBG_BEACON,
+                                       DPRINTF(sc, ATH_DBG_BEACON,
                                                "%s: beacon is officially "
                                                "stuck\n", __func__);
                                        ath9k_hw_dmaRegDump(ah);
@@ -542,13 +534,12 @@ void ath9k_beacon_tasklet(unsigned long data)
                                ath_bstuck_process(sc);
                        }
                }
-
                return;
        }
+
        if (sc->sc_bmisscount != 0) {
                if (sc->sc_flags & SC_OP_NO_RESET) {
-                       DPRINTF(sc,
-                               ATH_DBG_BEACON,
+                       DPRINTF(sc, ATH_DBG_BEACON,
                                "%s: resume beacon xmit after %u misses\n",
                                __func__, sc->sc_bmisscount);
                } else {
@@ -572,10 +563,12 @@ void ath9k_beacon_tasklet(unsigned long data)
        tsftu = TSF_TO_TU(tsf>>32, tsf);
        slot = ((tsftu % intval) * ATH_BCBUF) / intval;
        if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
+
        DPRINTF(sc, ATH_DBG_BEACON,
-                       "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
-                       __func__, slot, (unsigned long long) tsf, tsftu,
-                       intval, if_id);
+               "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
+               __func__, slot, (unsigned long long)tsf, tsftu,
+               intval, if_id);
+
        bfaddr = 0;
        if (if_id != ATH_IF_ID_ANY) {
                bf = ath_beacon_generate(sc, if_id);
@@ -632,9 +625,8 @@ void ath9k_beacon_tasklet(unsigned long data)
  *  Tasklet for Beacon Stuck processing
  *
  *  Processing for Beacon Stuck.
- *  Basically calls the ath_internal_reset function to reset the chip.
+ *  Basically resets the chip.
 */
-
 void ath_bstuck_process(struct ath_softc *sc)
 {
        DPRINTF(sc, ATH_DBG_BEACON,
@@ -658,13 +650,12 @@ void ath_bstuck_process(struct ath_softc *sc)
  * interrupt when we stop seeing beacons from the AP
  * we've associated with.
  */
-
 void ath_beacon_config(struct ath_softc *sc, int if_id)
 {
        struct ath_hal *ah = sc->sc_ah;
-       u32 nexttbtt, intval;
        struct ath_beacon_config conf;
        enum ath9k_opmode av_opmode;
+       u32 nexttbtt, intval;
 
        if (if_id != ATH_IF_ID_ANY)
                av_opmode = sc->sc_vaps[if_id]->av_opmode;
@@ -673,12 +664,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
 
        memzero(&conf, sizeof(struct ath_beacon_config));
 
-       /* FIXME: Use default values for now - Sujith */
-       /* Query beacon configuration first */
-       /*
-        * Protocol stack doesn't support dynamic beacon configuration,
-        * use default configurations.
-        */
        conf.beacon_interval = sc->hw->conf.beacon_int ?
                sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
        conf.listen_interval = 1;
@@ -687,8 +672,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
        conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
 
        /* extract tstamp from last beacon and convert to TU */
-       nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4),
-                            get_unaligned_le32(conf.u.last_tstamp));
+       nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp);
+
        /* XXX conditionalize multi-bss support? */
        if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
                /*
@@ -704,12 +689,14 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
        }
 
-       if (nexttbtt == 0)      /* e.g. for ap mode */
+       if (nexttbtt == 0)      /* e.g. for ap mode */
                nexttbtt = intval;
-       else if (intval)        /* NB: can be 0 for monitor mode */
+       else if (intval)        /* NB: can be 0 for monitor mode */
                nexttbtt = roundup(nexttbtt, intval);
+
        DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
                __func__, nexttbtt, intval, conf.beacon_interval);
+
        /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
        if (sc->sc_ah->ah_opmode == ATH9K_M_STA) {
                struct ath9k_beacon_state bs;
@@ -723,19 +710,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                 * last beacon we received (which may be none).
                 */
                dtimperiod = conf.dtim_period;
-               if (dtimperiod <= 0)        /* NB: 0 if not known */
+               if (dtimperiod <= 0)            /* NB: 0 if not known */
                        dtimperiod = 1;
                dtimcount = conf.dtim_count;
-               if (dtimcount >= dtimperiod)    /* NB: sanity check */
-                       dtimcount = 0;      /* XXX? */
-               cfpperiod = 1;          /* NB: no PCF support yet */
+               if (dtimcount >= dtimperiod)    /* NB: sanity check */
+                       dtimcount = 0;
+               cfpperiod = 1;                  /* NB: no PCF support yet */
                cfpcount = 0;
 
                sleepduration = conf.listen_interval * intval;
                if (sleepduration <= 0)
                        sleepduration = intval;
 
-#define FUDGE   2
+#define FUDGE 2
                /*
                 * Pull nexttbtt forward to reflect the current
                 * TSF and calculate dtim+cfp state for the result.
@@ -759,6 +746,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
                bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
                bs.bs_cfpmaxduration = 0;
+
                /*
                 * Calculate the number of consecutive beacons to miss
                 * before taking a BMISS interrupt.  The configuration
@@ -767,9 +755,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                 * result to at most 15 beacons.
                 */
                if (sleepduration > intval) {
-                       bs.bs_bmissthreshold =
-                               conf.listen_interval *
-                                       ATH_DEFAULT_BMISS_LIMIT / 2;
+                       bs.bs_bmissthreshold = conf.listen_interval *
+                               ATH_DEFAULT_BMISS_LIMIT / 2;
                } else {
                        bs.bs_bmissthreshold =
                                DIV_ROUND_UP(conf.bmiss_timeout, intval);
@@ -789,8 +776,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                 * XXX fixed at 100ms
                 */
 
-               bs.bs_sleepduration =
-                       roundup(IEEE80211_MS_TO_TU(100), sleepduration);
+               bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100),
+                                             sleepduration);
                if (bs.bs_sleepduration > bs.bs_dtimperiod)
                        bs.bs_sleepduration = bs.bs_dtimperiod;
 
@@ -834,9 +821,9 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
                if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) {
                        /*
                         * Pull nexttbtt forward to reflect the current
-                        * TSF .
+                        * TSF
                         */
-#define FUDGE   2
+#define FUDGE 2
                        if (!(intval & ATH9K_BEACON_RESET_TSF)) {
                                tsf = ath9k_hw_gettsf64(ah);
                                tsftu = TSF_TO_TU((u32)(tsf>>32),
index c262ef279ff30be89507f607ebda6d87241293d9..6c433a4d003e688eb7263e28c2a72feae6b365ec 100644 (file)
@@ -534,7 +534,8 @@ int ath_vap_attach(struct ath_softc *sc,
        avp->av_opmode = opmode;
        avp->av_bslot = -1;
 
-       ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+       if (opmode == ATH9K_M_HOSTAP)
+               ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
 
        sc->sc_vaps[if_id] = avp;
        sc->sc_nvaps++;
@@ -677,6 +678,12 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
        if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
                sc->sc_imask |= ATH9K_INT_CST;
 
+       /* Note: We disable MIB interrupts for now as we don't yet
+        * handle processing ANI, otherwise you will get an interrupt
+        * storm after about 7 hours of usage making the system unusable
+        * with huge latency. Once we do have ANI processing included
+        * we can re-enable this interrupt. */
+#if 0
        /*
         * Enable MIB interrupts when there are hardware phy counters.
         * Note we only do this (at the moment) for station mode.
@@ -685,6 +692,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
            ((sc->sc_ah->ah_opmode == ATH9K_M_STA) ||
             (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)))
                sc->sc_imask |= ATH9K_INT_MIB;
+#endif
        /*
         * Some hardware processes the TIM IE and fires an
         * interrupt when the TIM bit is set.  For hardware
@@ -1183,6 +1191,8 @@ void ath_deinit(struct ath_softc *sc)
 
        DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__);
 
+       tasklet_kill(&sc->intr_tq);
+       tasklet_kill(&sc->bcon_tasklet);
        ath_stop(sc);
        if (!(sc->sc_flags & SC_OP_INVALID))
                ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
index b66de29cf6621f21b4ff2a3495a1cdc283b53ee5..872f0c5a0b0e44a53145923f29385de82bc59353 100644 (file)
@@ -976,7 +976,6 @@ struct ath_softc {
        u32 sc_keymax;          /* size of key cache */
        DECLARE_BITMAP(sc_keymap, ATH_KEYMAX);  /* key use bit map */
        u8 sc_splitmic;         /* split TKIP MIC keys */
-       int sc_keytype;
 
        /* RX */
        struct list_head sc_rxbuf;
@@ -1001,6 +1000,7 @@ struct ath_softc {
        u32 sc_bhalq;
        u32 sc_bmisscount;
        u32 ast_be_xmit;        /* beacons transmitted */
+       u64 bc_tstamp;
 
        /* Rate */
        struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
index 0251e59f2f849a109e67d6f43a3297cd206136ad..272c758166091033b4b64889830434143a140cf6 100644 (file)
@@ -2526,6 +2526,11 @@ static void ath9k_ani_reset(struct ath_hal *ah)
        }
 }
 
+/*
+ * Process a MIB interrupt.  We may potentially be invoked because
+ * any of the MIB counters overflow/trigger so don't assume we're
+ * here because a PHY error counter triggered.
+ */
 void ath9k_hw_procmibevent(struct ath_hal *ah,
                           const struct ath9k_node_stats *stats)
 {
@@ -2533,18 +2538,20 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
        u32 phyCnt1, phyCnt2;
 
        DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n");
-
+       /* Reset these counters regardless */
        REG_WRITE(ah, AR_FILT_OFDM, 0);
        REG_WRITE(ah, AR_FILT_CCK, 0);
        if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
                REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
 
+       /* Clear the mib counters and save them in the stats */
        ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
        ahp->ah_stats.ast_nodestats = *stats;
 
        if (!DO_ANI(ah))
                return;
 
+       /* NB: these are not reset-on-read */
        phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
        phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
        if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
@@ -2552,6 +2559,7 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
                struct ar5416AniState *aniState = ahp->ah_curani;
                u32 ofdmPhyErrCnt, cckPhyErrCnt;
 
+               /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
                ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
                ahp->ah_stats.ast_ani_ofdmerrs +=
                        ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
@@ -2562,11 +2570,17 @@ void ath9k_hw_procmibevent(struct ath_hal *ah,
                        cckPhyErrCnt - aniState->cckPhyErrCount;
                aniState->cckPhyErrCount = cckPhyErrCnt;
 
+               /*
+                * NB: figure out which counter triggered.  If both
+                * trigger we'll only deal with one as the processing
+                * clobbers the error counter so the trigger threshold
+                * check will never be true.
+                */
                if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
                        ath9k_hw_ani_ofdm_err_trigger(ah);
                if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
                        ath9k_hw_ani_cck_err_trigger(ah);
-
+               /* NB: always restart to insure the h/w counters are reset */
                ath9k_ani_restart(ah);
        }
 }
index 1ba18006f475e87571f5718d1adc0865fd8cb838..2caba440316728ec75e1c4f85849978394c7deef 100644 (file)
@@ -204,8 +204,6 @@ static int ath_key_config(struct ath_softc *sc,
        if (!ret)
                return -EIO;
 
-       if (mac)
-               sc->sc_keytype = hk.kv_type;
        return 0;
 }
 
@@ -1507,7 +1505,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
        case DISABLE_KEY:
                ath_key_delete(sc, key);
                clear_bit(key->keyidx, sc->sc_keymap);
-               sc->sc_keytype = ATH9K_CIPHER_CLR;
                break;
        default:
                ret = -EINVAL;
@@ -1784,10 +1781,17 @@ static void ath_pci_remove(struct pci_dev *pdev)
 {
        struct ieee80211_hw *hw = pci_get_drvdata(pdev);
        struct ath_softc *sc = hw->priv;
+       enum ath9k_int status;
 
-       if (pdev->irq)
+       if (pdev->irq) {
+               ath9k_hw_set_interrupts(sc->sc_ah, 0);
+               /* clear the ISR */
+               ath9k_hw_getisr(sc->sc_ah, &status);
+               sc->sc_flags |= SC_OP_INVALID;
                free_irq(pdev->irq, sc);
+       }
        ath_detach(sc);
+
        pci_iounmap(pdev, sc->mem);
        pci_release_region(pdev, 0);
        pci_disable_device(pdev);
index 1cc9daf44550aac38cc231beb4e029a03c67c9de..cca2fc5b07654b3e17107b4acaf2b7893e328d53 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "core.h"
+/* FIXME: remove this include! */
 #include "../net/mac80211/rate.h"
 
 static u32 tx_triglevel_max;
@@ -1812,20 +1813,18 @@ static void ath_rc_sib_init(struct ath_rate_node *ath_rc_priv)
 }
 
 
-static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta)
+static void ath_setup_rates(struct ath_softc *sc,
+                           struct ieee80211_supported_band *sband,
+                           struct ieee80211_sta *sta,
+                           struct ath_rate_node *rc_priv)
 
 {
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_hw *hw = local_to_hw(local);
-       struct ath_softc *sc = hw->priv;
-       struct ath_rate_node *rc_priv = sta->rate_ctrl_priv;
        int i, j = 0;
 
        DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
 
-       sband =  local->hw.wiphy->bands[local->hw.conf.channel->band];
        for (i = 0; i < sband->n_bitrates; i++) {
-               if (sta->sta.supp_rates[local->hw.conf.channel->band] & BIT(i)) {
+               if (sta->supp_rates[sband->band] & BIT(i)) {
                        rc_priv->neg_rates.rs_rates[j]
                                = (sband->bitrates[i].bitrate * 2) / 10;
                        j++;
@@ -1852,19 +1851,17 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv)
 }
 
 /* Rate Control callbacks */
-static void ath_tx_status(void *priv, struct net_device *dev,
+static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
+                         struct ieee80211_sta *sta, void *priv_sta,
                          struct sk_buff *skb)
 {
        struct ath_softc *sc = priv;
        struct ath_tx_info_priv *tx_info_priv;
        struct ath_node *an;
-       struct sta_info *sta;
-       struct ieee80211_local *local;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr;
        __le16 fc;
 
-       local = hw_to_local(sc->hw);
        hdr = (struct ieee80211_hdr *)skb->data;
        fc = hdr->frame_control;
        tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
@@ -1873,8 +1870,7 @@ static void ath_tx_status(void *priv, struct net_device *dev,
        an = ath_node_find(sc, hdr->addr1);
        spin_unlock_bh(&sc->node_lock);
 
-       sta = sta_info_get(local, hdr->addr1);
-       if (!an || !sta || !ieee80211_is_data(fc)) {
+       if (!an || !priv_sta || !ieee80211_is_data(fc)) {
                if (tx_info->driver_data[0] != NULL) {
                        kfree(tx_info->driver_data[0]);
                        tx_info->driver_data[0] = NULL;
@@ -1882,24 +1878,22 @@ static void ath_tx_status(void *priv, struct net_device *dev,
                return;
        }
        if (tx_info->driver_data[0] != NULL) {
-               ath_rate_tx_complete(sc, an, sta->rate_ctrl_priv, tx_info_priv);
+               ath_rate_tx_complete(sc, an, priv_sta, tx_info_priv);
                kfree(tx_info->driver_data[0]);
                tx_info->driver_data[0] = NULL;
        }
 }
 
 static void ath_tx_aggr_resp(struct ath_softc *sc,
-                            struct sta_info *sta,
+                            struct ieee80211_supported_band *sband,
+                            struct ieee80211_sta *sta,
                             struct ath_node *an,
                             u8 tidno)
 {
-       struct ieee80211_hw *hw = sc->hw;
-       struct ieee80211_local *local;
        struct ath_atx_tid *txtid;
-       struct ieee80211_supported_band *sband;
        u16 buffersize = 0;
        int state;
-       DECLARE_MAC_BUF(mac);
+       struct sta_info *si;
 
        if (!(sc->sc_flags & SC_OP_TXAGGR))
                return;
@@ -1908,11 +1902,16 @@ static void ath_tx_aggr_resp(struct ath_softc *sc,
        if (!txtid->paused)
                return;
 
-       local = hw_to_local(sc->hw);
-       sband = hw->wiphy->bands[hw->conf.channel->band];
+       /*
+        * XXX: This is entirely busted, we aren't supposed to
+        *      access the sta from here because it's internal
+        *      to mac80211, and looking at the state without
+        *      locking is wrong too.
+        */
+       si = container_of(sta, struct sta_info, sta);
        buffersize = IEEE80211_MIN_AMPDU_BUF <<
                sband->ht_info.ampdu_factor; /* FIXME */
-       state = sta->ampdu_mlme.tid_state_tx[tidno];
+       state = si->ampdu_mlme.tid_state_tx[tidno];
 
        if (state & HT_ADDBA_RECEIVED_MSK) {
                txtid->addba_exchangecomplete = 1;
@@ -1928,18 +1927,15 @@ static void ath_tx_aggr_resp(struct ath_softc *sc,
        }
 }
 
-static void ath_get_rate(void *priv, struct net_device *dev,
-                        struct ieee80211_supported_band *sband,
-                        struct sk_buff *skb,
-                        struct rate_selection *sel)
+static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband,
+                        struct ieee80211_sta *sta, void *priv_sta,
+                        struct sk_buff *skb, struct rate_selection *sel)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct sta_info *sta;
-       struct ath_softc *sc = (struct ath_softc *)priv;
+       struct ath_softc *sc = priv;
        struct ieee80211_hw *hw = sc->hw;
        struct ath_tx_info_priv *tx_info_priv;
-       struct ath_rate_node *ath_rc_priv;
+       struct ath_rate_node *ath_rc_priv = priv_sta;
        struct ath_node *an;
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
        int is_probe = FALSE, chk, ret;
@@ -1955,8 +1951,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
        ASSERT(tx_info->driver_data[0] != NULL);
        tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
 
-       sta = sta_info_get(local, hdr->addr1);
-       lowest_idx = rate_lowest_index(local, sband, sta);
+       lowest_idx = rate_lowest_index(sband, sta);
        tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10;
        /* lowest rate for management and multicast/broadcast frames */
        if (!ieee80211_is_data(fc) ||
@@ -1965,8 +1960,6 @@ static void ath_get_rate(void *priv, struct net_device *dev,
                return;
        }
 
-       ath_rc_priv = sta->rate_ctrl_priv;
-
        /* Find tx rate for unicast frames */
        ath_rate_findrate(sc, ath_rc_priv,
                          ATH_11N_TXMAXTRY, 4,
@@ -1975,8 +1968,7 @@ static void ath_get_rate(void *priv, struct net_device *dev,
                          &is_probe,
                          false);
        if (is_probe)
-               sel->probe_idx = ((struct ath_tx_ratectrl *)
-                                 sta->rate_ctrl_priv)->probe_rate;
+               sel->probe_idx = ath_rc_priv->tx_ratectrl.probe_rate;
 
        /* Ratecontrol sometimes returns invalid rate index */
        if (tx_info_priv->rcs[0].rix != 0xff)
@@ -2020,37 +2012,31 @@ static void ath_get_rate(void *priv, struct net_device *dev,
                                                __func__,
                                                print_mac(mac, hdr->addr1));
                        } else if (chk == AGGR_EXCHANGE_PROGRESS)
-                               ath_tx_aggr_resp(sc, sta, an, tid);
+                               ath_tx_aggr_resp(sc, sband, sta, an, tid);
                }
        }
 }
 
-static void ath_rate_init(void *priv, void *priv_sta,
-                         struct ieee80211_local *local,
-                         struct sta_info *sta)
+static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
+                          struct ieee80211_sta *sta, void *priv_sta)
 {
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_hw *hw = local_to_hw(local);
-       struct ieee80211_conf *conf = &local->hw.conf;
-       struct ath_softc *sc = hw->priv;
+       struct ath_softc *sc = priv;
        struct ath_rate_node *ath_rc_priv = priv_sta;
        int i, j = 0;
 
        DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-       ath_setup_rates(local, sta);
-       if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
+       ath_setup_rates(sc, sband, sta, ath_rc_priv);
+       if (sc->hw->conf.flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
                for (i = 0; i < MCS_SET_SIZE; i++) {
-                       if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8)))
+                       if (sc->hw->conf.ht_conf.supp_mcs_set[i/8] & (1<<(i%8)))
                                ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
                        if (j == ATH_RATE_MAX)
                                break;
                }
                ath_rc_priv->neg_ht_rates.rs_nrates = j;
        }
-       ath_rc_node_update(hw, priv_sta);
+       ath_rc_node_update(sc->hw, priv_sta);
 }
 
 static void ath_rate_clear(void *priv)
@@ -2058,13 +2044,12 @@ static void ath_rate_clear(void *priv)
        return;
 }
 
-static void *ath_rate_alloc(struct ieee80211_local *local)
+static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
-       struct ieee80211_hw *hw = local_to_hw(local);
        struct ath_softc *sc = hw->priv;
 
        DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
-       return local->hw.priv;
+       return hw->priv;
 }
 
 static void ath_rate_free(void *priv)
@@ -2072,7 +2057,7 @@ static void ath_rate_free(void *priv)
        return;
 }
 
-static void *ath_rate_alloc_sta(void *priv, gfp_t gfp)
+static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
 {
        struct ath_softc *sc = priv;
        struct ath_vap *avp = sc->sc_vaps[0];
@@ -2092,7 +2077,8 @@ static void *ath_rate_alloc_sta(void *priv, gfp_t gfp)
        return rate_priv;
 }
 
-static void ath_rate_free_sta(void *priv, void *priv_sta)
+static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
+                             void *priv_sta)
 {
        struct ath_rate_node *rate_priv = priv_sta;
        struct ath_softc *sc = priv;
@@ -2111,7 +2097,7 @@ static struct rate_control_ops ath_rate_ops = {
        .alloc = ath_rate_alloc,
        .free = ath_rate_free,
        .alloc_sta = ath_rate_alloc_sta,
-       .free_sta = ath_rate_free_sta
+       .free_sta = ath_rate_free_sta,
 };
 
 int ath_rate_control_register(void)
index 3fc6641e8bf750a3d34c05768f3296abcf05bb96..25929059c7dc8d1aaf14f18eeb0e9c5f2ee7f46b 100644 (file)
@@ -239,11 +239,11 @@ static int ath_tx_prepare(struct ath_softc *sc,
                txctl->keyix = tx_info->control.hw_key->hw_key_idx;
                txctl->frmlen += tx_info->control.icv_len;
 
-               if (sc->sc_keytype == ATH9K_CIPHER_WEP)
+               if (tx_info->control.hw_key->alg == ALG_WEP)
                        txctl->keytype = ATH9K_KEY_TYPE_WEP;
-               else if (sc->sc_keytype == ATH9K_CIPHER_TKIP)
+               else if (tx_info->control.hw_key->alg == ALG_TKIP)
                        txctl->keytype = ATH9K_KEY_TYPE_TKIP;
-               else if (sc->sc_keytype == ATH9K_CIPHER_AES_CCM)
+               else if (tx_info->control.hw_key->alg == ALG_CCMP)
                        txctl->keytype = ATH9K_KEY_TYPE_AES;
        }
 
index bd65c485098c4bb8b33c0fa84d8fffcb0a677b1e..ecb02bdaab5be183821287d1d540a1eaad872d22 100644 (file)
@@ -2258,7 +2258,7 @@ static int atmel_get_freq(struct net_device *dev,
 
 static int atmel_set_scan(struct net_device *dev,
                          struct iw_request_info *info,
-                         struct iw_param *vwrq,
+                         struct iw_point *dwrq,
                          char *extra)
 {
        struct atmel_private *priv = netdev_priv(dev);
index 12617cd0b78eb0be40247cfec84e874935ef5e64..d2388e8d179a440dce544ec598d857cc3e8b5b5f 100644 (file)
@@ -158,7 +158,7 @@ static int atmel_probe(struct pcmcia_device *p_dev)
        DEBUG(0, "atmel_attach()\n");
 
        /* Interrupt setup */
-       p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+       p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
        p_dev->irq.Handler = NULL;
 
index 0f628a29d83346fa9fa09aa4bce3cd578822c1eb..3bf74e236abc699f0c0bf7469ad94e6606dd25f2 100644 (file)
@@ -815,7 +815,7 @@ void b43_dummy_transmission(struct b43_wldev *dev)
                        break;
                udelay(10);
        }
-       for (i = 0x00; i < 0x0A; i++) {
+       for (i = 0x00; i < 0x19; i++) {
                value = b43_read16(dev, 0x0690);
                if (!(value & 0x0100))
                        break;
@@ -4543,9 +4543,11 @@ static void b43_sprom_fixup(struct ssb_bus *bus)
                pdev = bus->host_pci;
                if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) ||
                    IS_PDEV(pdev, BROADCOM, 0x4320,    DELL, 0x0003) ||
+                   IS_PDEV(pdev, BROADCOM, 0x4320,      HP, 0x12f8) ||
                    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) ||
                    IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) ||
-                   IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013))
+                   IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013) ||
+                   IS_PDEV(pdev, BROADCOM, 0x4320, MOTOROLA, 0x7010))
                        bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST;
        }
 }
index 7b9e99adb8c385c9fd829bc08575fd8ae03cfab8..713753781f4007eb44ec93090f40c27e452474a1 100644 (file)
@@ -44,23 +44,6 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
        return 0;
 }
 
-/* Update the rfkill state */
-static void b43_rfkill_update_state(struct b43_wldev *dev)
-{
-       struct b43_rfkill *rfk = &(dev->wl->rfkill);
-
-       if (!dev->radio_hw_enable) {
-               rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED;
-               return;
-       }
-
-       if (!dev->phy.radio_on)
-               rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
-       else
-               rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
-
-}
-
 /* The poll callback for the hardware button. */
 static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
 {
@@ -78,7 +61,6 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
        if (unlikely(enabled != dev->radio_hw_enable)) {
                dev->radio_hw_enable = enabled;
                report_change = 1;
-               b43_rfkill_update_state(dev);
                b43info(wl, "Radio hardware status changed to %s\n",
                        enabled ? "ENABLED" : "DISABLED");
        }
@@ -188,6 +170,11 @@ void b43_rfkill_init(struct b43_wldev *dev)
                        "The built-in radio LED will not work.\n");
 #endif /* CONFIG_RFKILL_INPUT */
 
+#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE)
+       b43warn(wl, "The rfkill-input subsystem is not available. "
+               "The built-in radio LED will not work.\n");
+#endif
+
        err = input_register_polled_device(rfk->poll_dev);
        if (err)
                goto err_unreg_rfk;
index 476add97e9749bddde4ef20b6420e13beef21886..b32bf6a94f19d7543525ed562a89683bf893d168 100644 (file)
@@ -44,23 +44,6 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
        return 0;
 }
 
-/* Update the rfkill state */
-static void b43legacy_rfkill_update_state(struct b43legacy_wldev *dev)
-{
-       struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
-
-       if (!dev->radio_hw_enable) {
-               rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED;
-               return;
-       }
-
-       if (!dev->phy.radio_on)
-               rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED;
-       else
-               rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
-
-}
-
 /* The poll callback for the hardware button. */
 static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
 {
@@ -78,7 +61,6 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
        if (unlikely(enabled != dev->radio_hw_enable)) {
                dev->radio_hw_enable = enabled;
                report_change = 1;
-               b43legacy_rfkill_update_state(dev);
                b43legacyinfo(wl, "Radio hardware status changed to %s\n",
                        enabled ? "ENABLED" : "DISABLED");
        }
index a279bf1dc9b034d6a49f86f98d8d9b6d133cb740..6fc5e7361f267dad0e01deb1a5c2a155cdc72bc6 100644 (file)
@@ -36,8 +36,6 @@
 
 #include <linux/workqueue.h>
 
-#include "../net/mac80211/rate.h"
-
 #include "iwl-3945.h"
 
 #define RS_NAME "iwl-3945-rs"
@@ -319,10 +317,10 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta,
        }
 }
 
-static void rs_rate_init(void *priv_rate, void *priv_sta,
-                        struct ieee80211_local *local, struct sta_info *sta)
+static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband,
+                        struct ieee80211_sta *sta, void *priv_sta)
 {
-       struct iwl3945_rs_sta *rs_sta = (void *)sta->rate_ctrl_priv;
+       struct iwl3945_rs_sta *rs_sta = priv_sta;
        int i;
 
        IWL_DEBUG_RATE("enter\n");
@@ -333,22 +331,22 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
         * after assoc.. */
 
        for (i = IWL_RATE_COUNT - 1; i >= 0; i--) {
-               if (sta->sta.supp_rates[local->hw.conf.channel->band] & (1 << i)) {
+               if (sta->supp_rates[sband->band] & (1 << i)) {
                        rs_sta->last_txrate_idx = i;
                        break;
                }
        }
 
        /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */
-       if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
+       if (sband->band == IEEE80211_BAND_5GHZ)
                rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
 
        IWL_DEBUG_RATE("leave\n");
 }
 
-static void *rs_alloc(struct ieee80211_local *local)
+static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
-       return local->hw.priv;
+       return hw->priv;
 }
 
 /* rate scale requires free function to be implemented */
@@ -356,17 +354,24 @@ static void rs_free(void *priv)
 {
        return;
 }
+
 static void rs_clear(void *priv)
 {
        return;
 }
 
 
-static void *rs_alloc_sta(void *priv, gfp_t gfp)
+static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
 {
        struct iwl3945_rs_sta *rs_sta;
+       struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
        int i;
 
+       /*
+        * XXX: If it's using sta->drv_priv anyway, it might
+        *      as well just put all the information there.
+        */
+
        IWL_DEBUG_RATE("enter\n");
 
        rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp);
@@ -375,6 +380,8 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp)
                return NULL;
        }
 
+       psta->rs_sta = rs_sta;
+
        spin_lock_init(&rs_sta->lock);
 
        rs_sta->start_rate = IWL_RATE_INVALID;
@@ -400,10 +407,14 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp)
        return rs_sta;
 }
 
-static void rs_free_sta(void *priv, void *priv_sta)
+static void rs_free_sta(void *priv, struct ieee80211_sta *sta,
+                       void *priv_sta)
 {
+       struct iwl3945_sta_priv *psta = (void *) sta->drv_priv;
        struct iwl3945_rs_sta *rs_sta = priv_sta;
 
+       psta->rs_sta = NULL;
+
        IWL_DEBUG_RATE("enter\n");
        del_timer_sync(&rs_sta->rate_scale_flush);
        kfree(rs_sta);
@@ -445,26 +456,19 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate)
  * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by
  * the hardware for each rate.
  */
-static void rs_tx_status(void *priv_rate,
-                        struct net_device *dev,
+static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband,
+                        struct ieee80211_sta *sta, void *priv_sta,
                         struct sk_buff *skb)
 {
        u8 retries, current_count;
        int scale_rate_index, first_index, last_index;
        unsigned long flags;
-       struct sta_info *sta;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct iwl3945_rs_sta *rs_sta;
-       struct ieee80211_supported_band *sband;
+       struct iwl3945_rs_sta *rs_sta = priv_sta;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
        IWL_DEBUG_RATE("enter\n");
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-
        retries = info->status.retry_count;
        first_index = sband->bitrates[info->tx_rate_idx].hw_value;
        if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) {
@@ -472,17 +476,11 @@ static void rs_tx_status(void *priv_rate,
                return;
        }
 
-       rcu_read_lock();
-
-       sta = sta_info_get(local, hdr->addr1);
-       if (!sta || !sta->rate_ctrl_priv) {
-               rcu_read_unlock();
+       if (!priv_sta) {
                IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
                return;
        }
 
-       rs_sta = (void *)sta->rate_ctrl_priv;
-
        rs_sta->tx_packets++;
 
        scale_rate_index = first_index;
@@ -549,8 +547,6 @@ static void rs_tx_status(void *priv_rate,
 
        spin_unlock_irqrestore(&rs_sta->lock, flags);
 
-       rcu_read_unlock();
-
        IWL_DEBUG_RATE("leave\n");
 
        return;
@@ -634,16 +630,15 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta,
  * rate table and must reference the driver allocated rate table
  *
  */
-static void rs_get_rate(void *priv_rate, struct net_device *dev,
-                       struct ieee80211_supported_band *sband,
-                       struct sk_buff *skb,
-                       struct rate_selection *sel)
+static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
+                       struct ieee80211_sta *sta, void *priv_sta,
+                       struct sk_buff *skb, struct rate_selection *sel)
 {
        u8 low = IWL_RATE_INVALID;
        u8 high = IWL_RATE_INVALID;
        u16 high_low;
        int index;
-       struct iwl3945_rs_sta *rs_sta;
+       struct iwl3945_rs_sta *rs_sta = priv_sta;
        struct iwl3945_rate_scale_data *window = NULL;
        int current_tpt = IWL_INV_TPT;
        int low_tpt = IWL_INV_TPT;
@@ -651,34 +646,25 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
        u32 fail_count;
        s8 scale_action = 0;
        unsigned long flags;
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct sta_info *sta;
        u16 fc, rate_mask;
-       struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate;
+       struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r;
        DECLARE_MAC_BUF(mac);
 
        IWL_DEBUG_RATE("enter\n");
 
-       rcu_read_lock();
-
-       sta = sta_info_get(local, hdr->addr1);
-
        /* Send management frames and broadcast/multicast data using lowest
         * rate. */
        fc = le16_to_cpu(hdr->frame_control);
        if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
            is_multicast_ether_addr(hdr->addr1) ||
-           !sta || !sta->rate_ctrl_priv) {
+           !sta || !priv_sta) {
                IWL_DEBUG_RATE("leave: No STA priv data to update!\n");
-               sel->rate_idx = rate_lowest_index(local, sband, sta);
-               rcu_read_unlock();
+               sel->rate_idx = rate_lowest_index(sband, sta);
                return;
        }
 
-       rs_sta = (void *)sta->rate_ctrl_priv;
-
-       rate_mask = sta->sta.supp_rates[sband->band];
+       rate_mask = sta->supp_rates[sband->band];
        index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1);
 
        if (sband->band == IEEE80211_BAND_5GHZ)
@@ -811,8 +797,6 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
        else
                sel->rate_idx = rs_sta->last_txrate_idx;
 
-       rcu_read_unlock();
-
        IWL_DEBUG_RATE("leave: %d\n", index);
 }
 
@@ -829,114 +813,28 @@ static struct rate_control_ops rs_ops = {
        .free_sta = rs_free_sta,
 };
 
-int iwl3945_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
-{
-       struct ieee80211_local *local = hw_to_local(hw);
-       struct iwl3945_priv *priv = hw->priv;
-       struct iwl3945_rs_sta *rs_sta;
-       struct sta_info *sta;
-       unsigned long flags;
-       int count = 0, i;
-       u32 samples = 0, success = 0, good = 0;
-       unsigned long now = jiffies;
-       u32 max_time = 0;
-
-       rcu_read_lock();
-
-       sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
-       if (!sta || !sta->rate_ctrl_priv) {
-               if (sta)
-                       IWL_DEBUG_RATE("leave - no private rate data!\n");
-               else
-                       IWL_DEBUG_RATE("leave - no station!\n");
-               rcu_read_unlock();
-               return sprintf(buf, "station %d not found\n", sta_id);
-       }
-
-       rs_sta = (void *)sta->rate_ctrl_priv;
-       spin_lock_irqsave(&rs_sta->lock, flags);
-       i = IWL_RATE_54M_INDEX;
-       while (1) {
-               u64 mask;
-               int j;
-
-               count +=
-                   sprintf(&buf[count], " %2dMbs: ", iwl3945_rates[i].ieee / 2);
-
-               mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1));
-               for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1)
-                       buf[count++] =
-                           (rs_sta->win[i].data & mask) ? '1' : '0';
-
-               samples += rs_sta->win[i].counter;
-               good += rs_sta->win[i].success_counter;
-               success += rs_sta->win[i].success_counter *
-                                               iwl3945_rates[i].ieee;
-
-               if (rs_sta->win[i].stamp) {
-                       int delta =
-                           jiffies_to_msecs(now - rs_sta->win[i].stamp);
-
-                       if (delta > max_time)
-                               max_time = delta;
-
-                       count += sprintf(&buf[count], "%5dms\n", delta);
-               } else
-                       buf[count++] = '\n';
-
-               j = iwl3945_get_prev_ieee_rate(i);
-               if (j == i)
-                       break;
-               i = j;
-       }
-       spin_unlock_irqrestore(&rs_sta->lock, flags);
-       rcu_read_unlock();
-
-       /* Display the average rate of all samples taken.
-        *
-        * NOTE:  We multiple # of samples by 2 since the IEEE measurement
-        * added from iwl3945_rates is actually 2X the rate */
-       if (samples)
-               count += sprintf(
-                       &buf[count],
-                       "\nAverage rate is %3d.%02dMbs over last %4dms\n"
-                       "%3d%% success (%d good packets over %d tries)\n",
-                       success / (2 * samples), (success * 5 / samples) % 10,
-                       max_time, good * 100 / samples, good, samples);
-       else
-               count += sprintf(&buf[count], "\nAverage rate: 0Mbs\n");
-
-       return count;
-}
-
 void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 {
        struct iwl3945_priv *priv = hw->priv;
        s32 rssi = 0;
        unsigned long flags;
-       struct ieee80211_local *local = hw_to_local(hw);
        struct iwl3945_rs_sta *rs_sta;
-       struct sta_info *sta;
+       struct ieee80211_sta *sta;
+       struct iwl3945_sta_priv *psta;
 
        IWL_DEBUG_RATE("enter\n");
 
-       if (!local->rate_ctrl->ops->name ||
-           strcmp(local->rate_ctrl->ops->name, RS_NAME)) {
-               IWL_WARNING("iwl-3945-rs not selected as rate control algo!\n");
-               IWL_DEBUG_RATE("leave - mac80211 picked the wrong RC algo.\n");
-               return;
-       }
-
        rcu_read_lock();
 
-       sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
-       if (!sta || !sta->rate_ctrl_priv) {
+       sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
+       psta = (void *) sta->drv_priv;
+       if (!sta || !psta) {
                IWL_DEBUG_RATE("leave - no private rate data!\n");
                rcu_read_unlock();
                return;
        }
 
-       rs_sta = (void *)sta->rate_ctrl_priv;
+       rs_sta = psta->rs_sta;
 
        spin_lock_irqsave(&rs_sta->lock, flags);
 
index f085d330bdcf760a03efaa55020736fa84c2e1d0..98b17ae6ef246d62720760cf4c5416e10300eb4d 100644 (file)
@@ -175,15 +175,6 @@ static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index)
        return rate;
 }
 
-/**
- * iwl3945_fill_rs_info - Fill an output text buffer with the rate representation
- *
- * NOTE:  This is provided as a quick mechanism for a user to visualize
- * the performance of the rate control algorithm and is not meant to be
- * parsed software.
- */
-extern int iwl3945_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id);
-
 /**
  * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
  *
index 2a4933b5fb648de04f227765c4db0ff0489dc3a9..bdd32475b99ca6b0ca7ae1562f85b878edfa55fc 100644 (file)
@@ -73,6 +73,10 @@ extern struct pci_device_id iwl3945_hw_card_ids[];
 extern int iwl3945_param_hwcrypto;
 extern int iwl3945_param_queues_num;
 
+struct iwl3945_sta_priv {
+       struct iwl3945_rs_sta *rs_sta;
+};
+
 enum iwl3945_antenna {
        IWL_ANTENNA_DIVERSITY,
        IWL_ANTENNA_MAIN,
index 8b57b390c8bace21e6407e1ec51e00d1d590e0c2..93944de923cafd0913979e1f45bf8a36023d2285 100644 (file)
@@ -35,8 +35,6 @@
 
 #include <linux/workqueue.h>
 
-#include "../net/mac80211/rate.h"
-
 #include "iwl-dev.h"
 #include "iwl-sta.h"
 #include "iwl-core.h"
@@ -169,9 +167,9 @@ struct iwl_lq_sta {
 };
 
 static void rs_rate_scale_perform(struct iwl_priv *priv,
-                                  struct net_device *dev,
                                   struct ieee80211_hdr *hdr,
-                                  struct sta_info *sta);
+                                  struct ieee80211_sta *sta,
+                                  struct iwl_lq_sta *lq_sta);
 static void rs_fill_link_cmd(const struct iwl_priv *priv,
                             struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
 
@@ -357,20 +355,20 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid)
 
 static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
                                      struct iwl_lq_sta *lq_data, u8 tid,
-                                     struct sta_info *sta)
+                                     struct ieee80211_sta *sta)
 {
        DECLARE_MAC_BUF(mac);
 
        if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
                IWL_DEBUG_HT("Starting Tx agg: STA: %s tid: %d\n",
-                               print_mac(mac, sta->sta.addr), tid);
-               ieee80211_start_tx_ba_session(priv->hw, sta->sta.addr, tid);
+                               print_mac(mac, sta->addr), tid);
+               ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid);
        }
 }
 
 static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
                              struct iwl_lq_sta *lq_data,
-                             struct sta_info *sta)
+                             struct ieee80211_sta *sta)
 {
        if ((tid < TID_MAX_LOAD_COUNT))
                rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
@@ -770,7 +768,8 @@ out:
 /*
  * mac80211 sends us Tx status
  */
-static void rs_tx_status(void *priv_rate, struct net_device *dev,
+static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
+                        struct ieee80211_sta *sta, void *priv_sta,
                         struct sk_buff *skb)
 {
        int status;
@@ -778,11 +777,9 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
        int rs_index, index = 0;
        struct iwl_lq_sta *lq_sta;
        struct iwl_link_quality_cmd *table;
-       struct sta_info *sta;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_hw *hw = local_to_hw(local);
+       struct iwl_priv *priv = (struct iwl_priv *)priv_r;
+       struct ieee80211_hw *hw = priv->hw;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct iwl_rate_scale_data *window = NULL;
        struct iwl_rate_scale_data *search_win = NULL;
@@ -808,15 +805,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
        if (retries > 15)
                retries = 15;
 
-       rcu_read_lock();
-
-       sta = sta_info_get(local, hdr->addr1);
-
-       if (!sta || !sta->rate_ctrl_priv)
-               goto out;
-
-
-       lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
+       lq_sta = (struct iwl_lq_sta *)priv_sta;
 
        if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
            !lq_sta->ibss_sta_added)
@@ -962,9 +951,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
        }
 
        /* See if there's a better rate or modulation mode to try. */
-       rs_rate_scale_perform(priv, dev, hdr, sta);
+       rs_rate_scale_perform(priv, hdr, sta, lq_sta);
 out:
-       rcu_read_unlock();
        return;
 }
 
@@ -1140,7 +1128,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
 static int rs_switch_to_mimo2(struct iwl_priv *priv,
                             struct iwl_lq_sta *lq_sta,
                             struct ieee80211_conf *conf,
-                            struct sta_info *sta,
+                            struct ieee80211_sta *sta,
                             struct iwl_scale_tbl_info *tbl, int index)
 {
        u16 rate_mask;
@@ -1148,10 +1136,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
        s8 is_green = lq_sta->is_green;
 
        if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
-           !sta->sta.ht_info.ht_supported)
+           !sta->ht_info.ht_supported)
                return -1;
 
-       if (((sta->sta.ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
+       if (((sta->ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
                                                == WLAN_HT_CAP_SM_PS_STATIC)
                return -1;
 
@@ -1208,7 +1196,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
 static int rs_switch_to_siso(struct iwl_priv *priv,
                             struct iwl_lq_sta *lq_sta,
                             struct ieee80211_conf *conf,
-                            struct sta_info *sta,
+                            struct ieee80211_sta *sta,
                             struct iwl_scale_tbl_info *tbl, int index)
 {
        u16 rate_mask;
@@ -1216,7 +1204,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
        s32 rate;
 
        if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
-           !sta->sta.ht_info.ht_supported)
+           !sta->ht_info.ht_supported)
                return -1;
 
        IWL_DEBUG_RATE("LQ: try to switch to SISO\n");
@@ -1268,7 +1256,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
 static int rs_move_legacy_other(struct iwl_priv *priv,
                                struct iwl_lq_sta *lq_sta,
                                struct ieee80211_conf *conf,
-                               struct sta_info *sta,
+                               struct ieee80211_sta *sta,
                                int index)
 {
        struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1376,7 +1364,7 @@ out:
 static int rs_move_siso_to_other(struct iwl_priv *priv,
                                 struct iwl_lq_sta *lq_sta,
                                 struct ieee80211_conf *conf,
-                                struct sta_info *sta, int index)
+                                struct ieee80211_sta *sta, int index)
 {
        u8 is_green = lq_sta->is_green;
        struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1487,7 +1475,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
 static int rs_move_mimo_to_other(struct iwl_priv *priv,
                                 struct iwl_lq_sta *lq_sta,
                                 struct ieee80211_conf *conf,
-                                struct sta_info *sta, int index)
+                                struct ieee80211_sta *sta, int index)
 {
        s8 is_green = lq_sta->is_green;
        struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1680,12 +1668,11 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
  * Do rate scaling and search for new modulation mode.
  */
 static void rs_rate_scale_perform(struct iwl_priv *priv,
-                                 struct net_device *dev,
                                  struct ieee80211_hdr *hdr,
-                                 struct sta_info *sta)
+                                 struct ieee80211_sta *sta,
+                                 struct iwl_lq_sta *lq_sta)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_hw *hw = local_to_hw(local);
+       struct ieee80211_hw *hw = priv->hw;
        struct ieee80211_conf *conf = &hw->conf;
        int low = IWL_RATE_INVALID;
        int high = IWL_RATE_INVALID;
@@ -1700,7 +1687,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
        __le16 fc;
        u16 rate_mask;
        u8 update_lq = 0;
-       struct iwl_lq_sta *lq_sta;
        struct iwl_scale_tbl_info *tbl, *tbl1;
        u16 rate_scale_index_msk = 0;
        u32 rate;
@@ -1721,11 +1707,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                return;
        }
 
-       if (!sta || !sta->rate_ctrl_priv)
+       if (!sta || !lq_sta)
                return;
 
-       lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
-       lq_sta->supp_rates = sta->sta.supp_rates[lq_sta->band];
+       lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
 
        tid = rs_tl_add_packet(lq_sta, hdr);
 
@@ -2064,9 +2049,9 @@ out:
 
 static void rs_initialize_lq(struct iwl_priv *priv,
                             struct ieee80211_conf *conf,
-                            struct sta_info *sta)
+                            struct ieee80211_sta *sta,
+                            struct iwl_lq_sta *lq_sta)
 {
-       struct iwl_lq_sta *lq_sta;
        struct iwl_scale_tbl_info *tbl;
        int rate_idx;
        int i;
@@ -2075,10 +2060,9 @@ static void rs_initialize_lq(struct iwl_priv *priv,
        u8 active_tbl = 0;
        u8 valid_tx_ant;
 
-       if (!sta || !sta->rate_ctrl_priv)
+       if (!sta || !lq_sta)
                goto out;
 
-       lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
        i = lq_sta->last_txrate_idx;
 
        if ((lq_sta->lq.sta_id == 0xff) &&
@@ -2119,37 +2103,30 @@ static void rs_initialize_lq(struct iwl_priv *priv,
        return;
 }
 
-static void rs_get_rate(void *priv_rate, struct net_device *dev,
-                       struct ieee80211_supported_band *sband,
-                       struct sk_buff *skb,
-                       struct rate_selection *sel)
+static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband,
+                       struct ieee80211_sta *sta, void *priv_sta,
+                       struct sk_buff *skb, struct rate_selection *sel)
 {
 
        int i;
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_conf *conf = &local->hw.conf;
+       struct iwl_priv *priv = (struct iwl_priv *)priv_r;
+       struct ieee80211_conf *conf = &priv->hw->conf;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct sta_info *sta;
        __le16 fc;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
        struct iwl_lq_sta *lq_sta;
 
        IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n");
 
-       rcu_read_lock();
-
-       sta = sta_info_get(local, hdr->addr1);
-
        /* Send management frames and broadcast/multicast data using lowest
         * rate. */
        fc = hdr->frame_control;
        if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
-           !sta || !sta->rate_ctrl_priv) {
-               sel->rate_idx = rate_lowest_index(local, sband, sta);
-               goto out;
+           !sta || !priv_sta) {
+               sel->rate_idx = rate_lowest_index(sband, sta);
+               return;
        }
 
-       lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv;
+       lq_sta = (struct iwl_lq_sta *)priv_sta;
        i = lq_sta->last_txrate_idx;
 
        if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
@@ -2167,23 +2144,22 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev,
                        lq_sta->lq.sta_id = sta_id;
                        lq_sta->lq.rs_table[0].rate_n_flags = 0;
                        lq_sta->ibss_sta_added = 1;
-                       rs_initialize_lq(priv, conf, sta);
+                       rs_initialize_lq(priv, conf, sta, lq_sta);
                }
        }
 
        if ((i < 0) || (i > IWL_RATE_COUNT)) {
-               sel->rate_idx = rate_lowest_index(local, sband, sta);
-               goto out;
+               sel->rate_idx = rate_lowest_index(sband, sta);
+               return;
        }
 
        if (sband->band == IEEE80211_BAND_5GHZ)
                i -= IWL_FIRST_OFDM_RATE;
        sel->rate_idx = i;
-out:
-       rcu_read_unlock();
 }
 
-static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
+static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
+                         gfp_t gfp)
 {
        struct iwl_lq_sta *lq_sta;
        struct iwl_priv *priv;
@@ -2206,20 +2182,16 @@ static void *rs_alloc_sta(void *priv_rate, gfp_t gfp)
        return lq_sta;
 }
 
-static void rs_rate_init(void *priv_rate, void *priv_sta,
-                        struct ieee80211_local *local,
-                        struct sta_info *sta)
+static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
+                        struct ieee80211_sta *sta, void *priv_sta)
 {
        int i, j;
-       struct ieee80211_conf *conf = &local->hw.conf;
-       struct ieee80211_supported_band *sband;
-       struct iwl_priv *priv = (struct iwl_priv *)priv_rate;
+       struct iwl_priv *priv = (struct iwl_priv *)priv_r;
+       struct ieee80211_conf *conf = &priv->hw->conf;
        struct iwl_lq_sta *lq_sta = priv_sta;
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
        lq_sta->flush_timer = 0;
-       lq_sta->supp_rates = sta->sta.supp_rates[sband->band];
+       lq_sta->supp_rates = sta->supp_rates[sband->band];
        for (j = 0; j < LQ_SIZE; j++)
                for (i = 0; i < IWL_RATE_COUNT; i++)
                        rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
@@ -2232,17 +2204,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
 
        lq_sta->ibss_sta_added = 0;
        if (priv->iw_mode == NL80211_IFTYPE_AP) {
-               u8 sta_id = iwl_find_station(priv, sta->sta.addr);
+               u8 sta_id = iwl_find_station(priv, sta->addr);
                DECLARE_MAC_BUF(mac);
 
                /* for IBSS the call are from tasklet */
                IWL_DEBUG_RATE("LQ: ADD station %s\n",
-                            print_mac(mac, sta->sta.addr));
+                            print_mac(mac, sta->addr));
 
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_RATE("LQ: ADD station %s\n",
-                                      print_mac(mac, sta->sta.addr));
-                       sta_id = iwl_add_station_flags(priv, sta->sta.addr,
+                                      print_mac(mac, sta->addr));
+                       sta_id = iwl_add_station_flags(priv, sta->addr,
                                                        0, CMD_ASYNC, NULL);
                }
                if ((sta_id != IWL_INVALID_STATION)) {
@@ -2256,11 +2228,11 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
        /* Find highest tx rate supported by hardware and destination station */
        lq_sta->last_txrate_idx = 3;
        for (i = 0; i < sband->n_bitrates; i++)
-               if (sta->sta.supp_rates[sband->band] & BIT(i))
+               if (sta->supp_rates[sband->band] & BIT(i))
                        lq_sta->last_txrate_idx = i;
 
        /* For MODE_IEEE80211A, skip over cck rates in global rate table */
-       if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
+       if (sband->band == IEEE80211_BAND_5GHZ)
                lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
 
        lq_sta->is_dup = 0;
@@ -2301,7 +2273,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
        lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
        lq_sta->drv = priv;
 
-       rs_initialize_lq(priv, conf, sta);
+       rs_initialize_lq(priv, conf, sta, lq_sta);
 }
 
 static void rs_fill_link_cmd(const struct iwl_priv *priv,
@@ -2423,9 +2395,9 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
        lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
 }
 
-static void *rs_alloc(struct ieee80211_local *local)
+static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
 {
-       return local->hw.priv;
+       return hw->priv;
 }
 /* rate scale requires free function to be implemented */
 static void rs_free(void *priv_rate)
@@ -2446,12 +2418,12 @@ static void rs_clear(void *priv_rate)
 #endif /* CONFIG_IWLWIFI_DEBUG */
 }
 
-static void rs_free_sta(void *priv_rate, void *priv_sta)
+static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta,
+                       void *priv_sta)
 {
        struct iwl_lq_sta *lq_sta = priv_sta;
-       struct iwl_priv *priv;
+       struct iwl_priv *priv = priv_r;
 
-       priv = (struct iwl_priv *)priv_rate;
        IWL_DEBUG_RATE("enter\n");
        kfree(lq_sta);
        IWL_DEBUG_RATE("leave\n");
index 2737627697676e72c33b14cd2488be1c993b05e0..204abab764491a438659961958aa0df42353ff82 100644 (file)
@@ -2504,8 +2504,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
 
        priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
 
-       if (priv->current_ht_config.is_ht)
-               iwl_set_rxon_ht(priv, &priv->current_ht_config);
+       iwl_set_rxon_ht(priv, &priv->current_ht_config);
 
        iwl_set_rxon_chain(priv);
        priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
@@ -2568,8 +2567,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
        iwl_chain_noise_reset(priv);
        priv->start_calib = 1;
 
-       /* we have just associated, don't start scan too early */
-       priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
 }
 
 static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
@@ -2878,6 +2875,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
                goto out;
        }
 
+       if (conf->flags & IEEE80211_CONF_PS)
+               ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
+       else
+               ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
+       if (ret)
+               IWL_DEBUG_MAC80211("Error setting power level\n");
+
        IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n",
                           priv->tx_power_user_lmt, conf->power_level);
 
@@ -3171,6 +3175,10 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
                        priv->power_data.dtim_period = bss_conf->dtim_period;
                        priv->timestamp = bss_conf->timestamp;
                        priv->assoc_capability = bss_conf->assoc_capability;
+
+                       /* we have just associated, don't start scan too early
+                        * leave time for EAPOL exchange to complete
+                        */
                        priv->next_scan_jiffies = jiffies +
                                        IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
                        mutex_lock(&priv->mutex);
@@ -3189,9 +3197,9 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw,
 
 static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
 {
-       int ret;
        unsigned long flags;
        struct iwl_priv *priv = hw->priv;
+       int ret;
 
        IWL_DEBUG_MAC80211("enter\n");
 
@@ -3210,20 +3218,27 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len)
                goto out_unlock;
        }
 
-       /* we don't schedule scan within next_scan_jiffies period */
+       /* We don't schedule scan within next_scan_jiffies period.
+        * Avoid scanning during possible EAPOL exchange, return
+        * success immediately.
+        */
        if (priv->next_scan_jiffies &&
            time_after(priv->next_scan_jiffies, jiffies)) {
                IWL_DEBUG_SCAN("scan rejected: within next scan period\n");
-               ret = -EAGAIN;
+               queue_work(priv->workqueue, &priv->scan_completed);
+               ret = 0;
                goto out_unlock;
        }
+
        /* if we just finished scan ask for delay */
        if (iwl_is_associated(priv) && priv->last_scan_jiffies &&
            time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) {
                IWL_DEBUG_SCAN("scan rejected: within previous scan period\n");
-               ret = -EAGAIN;
+               queue_work(priv->workqueue, &priv->scan_completed);
+               ret = 0;
                goto out_unlock;
        }
+
        if (ssid_len) {
                priv->one_direct_scan = 1;
                priv->direct_ssid_len =  min_t(u8, ssid_len, IW_ESSID_MAX_SIZE);
@@ -4228,13 +4243,13 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        pci_set_master(pdev);
 
-       err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
+       err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
        if (!err)
-               err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+               err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
        if (err) {
-               err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (!err)
-                       err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+                       err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
                /* both attempts failed: */
                if (err) {
                        printk(KERN_WARNING "%s: No suitable DMA available.\n",
index d80184ee911c0c72b7e03e4d4d30847dcc0d4388..4c312c55f90cf49838af8954e0e891a0893af99c 100644 (file)
@@ -646,8 +646,14 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
        struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
        u32 val;
 
-       if (!ht_info->is_ht)
+       if (!ht_info->is_ht) {
+               rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
+                       RXON_FLG_CHANNEL_MODE_PURE_40_MSK |
+                       RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
+                       RXON_FLG_FAT_PROT_MSK |
+                       RXON_FLG_HT_PROT_MSK);
                return;
+       }
 
        /* Set up channel bandwidth:  20 MHz only, or 20/40 mixed if fat ok */
        if (iwl_is_fat_tx_allowed(priv, NULL))
@@ -697,8 +703,12 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
 }
 EXPORT_SYMBOL(iwl_set_rxon_ht);
 
-/*
- * Determine how many receiver/antenna chains to use.
+#define IWL_NUM_RX_CHAINS_MULTIPLE     3
+#define IWL_NUM_RX_CHAINS_SINGLE       2
+#define IWL_NUM_IDLE_CHAINS_DUAL       2
+#define IWL_NUM_IDLE_CHAINS_SINGLE     1
+
+/* Determine how many receiver/antenna chains to use.
  * More provides better reception via diversity.  Fewer saves power.
  * MIMO (dual stream) requires at least 2, but works better with 3.
  * This does not determine *which* chains to use, just how many.
@@ -711,9 +721,9 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
        /* # of Rx chains to use when expecting MIMO. */
        if (is_single || (!is_cam && (priv->current_ht_config.sm_ps ==
                                                 WLAN_HT_CAP_SM_PS_STATIC)))
-               return 2;
+               return IWL_NUM_RX_CHAINS_SINGLE;
        else
-               return 3;
+               return IWL_NUM_RX_CHAINS_MULTIPLE;
 }
 
 static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
@@ -724,10 +734,11 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
        switch (priv->current_ht_config.sm_ps) {
        case WLAN_HT_CAP_SM_PS_STATIC:
        case WLAN_HT_CAP_SM_PS_DYNAMIC:
-               idle_cnt = (is_cam) ? 2 : 1;
+               idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL :
+                                       IWL_NUM_IDLE_CHAINS_SINGLE;
                break;
        case WLAN_HT_CAP_SM_PS_DISABLED:
-               idle_cnt = (is_cam) ? active_cnt : 1;
+               idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE;
                break;
        case WLAN_HT_CAP_SM_PS_INVALID:
        default:
@@ -796,7 +807,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
 
        priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
 
-       if (!is_single && (active_rx_cnt >= 2) && is_cam)
+       if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
                priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
        else
                priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
index 52629fbd835a19e199d5a821bb3c31ac1b09020a..662edf4f8d226a13e8ce915e9c2aa085d581adc5 100644 (file)
@@ -64,7 +64,7 @@
 #define CSR_BASE    (0x000)
 
 #define CSR_HW_IF_CONFIG_REG    (CSR_BASE+0x000) /* hardware interface config */
-#define CSR_INT_COALESCING      (CSR_BASE+0x004) /* accum ints, 32-usec units */
+#define CSR_INT_COALESCING     (CSR_BASE+0x004) /* accum ints, 32-usec units */
 #define CSR_INT                 (CSR_BASE+0x008) /* host interrupt status/ack */
 #define CSR_INT_MASK            (CSR_BASE+0x00c) /* host interrupt enable */
 #define CSR_FH_INT_STATUS       (CSR_BASE+0x010) /* busmaster int status/ack*/
index cd11c0ca29918bf75ff2d606885f3cfcd1195de7..a72efdf6d1dd20160f5bf1526717007615ad875e 100644 (file)
 #define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MSK (0x00F00000) /* bits 20-23 */
 #define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MSK (0xC0000000) /* bits 30-31*/
 
-#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT  (20)
-#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_BITSHIFT        (4)
+#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS       (20)
+#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS     (4)
 #define RX_RB_TIMEOUT  (0x10)
 
 #define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL         (0x00000000)
 #define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_12K   (0x00020000)
 #define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_16K   (0x00030000)
 
-#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL       (0x00000000)
-#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL     (0x00001000)
+#define FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY              (0x00000004)
+#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL    (0x00000000)
+#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL  (0x00001000)
 
 
 /**
index 38b2946b1d81b81aa8b6ddd260d189f0d06c9bde..7cde9d76ff5df438b335996f1b602cf4e14dd9dc 100644 (file)
@@ -376,7 +376,9 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 {
        int ret;
        unsigned long flags;
-       unsigned int rb_size;
+       u32 rb_size;
+       const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
+       const u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT why this stalls RX */
 
        spin_lock_irqsave(&priv->lock, flags);
        ret = iwl_grab_nic_access(priv);
@@ -398,26 +400,32 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 
        /* Tell device where to find RBD circular buffer in DRAM */
        iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
-                          rxq->dma_addr >> 8);
+                          (u32)(rxq->dma_addr >> 8));
 
        /* Tell device where in DRAM to update its Rx status */
        iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
                           (priv->shared_phys + priv->rb_closed_offset) >> 4);
 
-       /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */
+       /* Enable Rx DMA
+        * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set becuase of HW bug in
+        *      the credit mechanism in 5000 HW RX FIFO
+        * Direct rx interrupts to hosts
+        * Rx buffer size 4 or 8k
+        * RB timeout 0x10
+        * 256 RBDs
+        */
        iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
                           FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
+                          FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
                           FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
-                          rb_size |
-                            /* 0x10 << 4 | */
-                          (RX_QUEUE_SIZE_LOG <<
-                             FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT));
-
-       /*
-        * iwl_write32(priv,CSR_INT_COAL_REG,0);
-        */
+                          rb_size|
+                          (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
+                          (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
 
        iwl_release_nic_access(priv);
+
+       iwl_write32(priv, CSR_INT_COALESCING, 0x40);
+
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
index 09c264be0496d5cca627501e74a4eb2cd98f038a..bf855c35b0c1258953c3bf653aab386d895551c7 100644 (file)
@@ -463,11 +463,6 @@ void iwl_init_scan_params(struct iwl_priv *priv)
 
 int iwl_scan_initiate(struct iwl_priv *priv)
 {
-       if (priv->iw_mode == NL80211_IFTYPE_AP) {
-               IWL_ERROR("APs don't scan.\n");
-               return 0;
-       }
-
        if (!iwl_is_ready_rf(priv)) {
                IWL_DEBUG_SCAN("Aborting scan due to not ready.\n");
                return -EIO;
@@ -479,8 +474,7 @@ int iwl_scan_initiate(struct iwl_priv *priv)
        }
 
        if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
-               IWL_DEBUG_SCAN("Scan request while abort pending.  "
-                              "Queuing.\n");
+               IWL_DEBUG_SCAN("Scan request while abort pending\n");
                return -EAGAIN;
        }
 
index e9feca4033f93834d39b88f6b3d85a9df1682e3c..907a53ebc6e4dc62fc7a5226b6706af72d1e0d85 100644 (file)
@@ -1200,10 +1200,9 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
        /* If a Tx command is being handled and it isn't in the actual
         * command queue then there a command routing bug has been introduced
         * in the queue management code. */
-       if (txq_id != IWL_CMD_QUEUE_NUM)
-               IWL_ERROR("Error wrong command queue %d command id 0x%X\n",
-                         txq_id, pkt->hdr.cmd);
-       BUG_ON(txq_id != IWL_CMD_QUEUE_NUM);
+       if (WARN(txq_id != IWL_CMD_QUEUE_NUM,
+                "wrong command queue %d, command id 0x%X\n", txq_id, pkt->hdr.cmd))
+               return;
 
        cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
        cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
index 62b26befddc5d241974be68116147c9dff96049d..d15a2c9979549983316a1981bdc07edf27581c54 100644 (file)
@@ -7370,15 +7370,6 @@ static ssize_t show_temperature(struct device *d,
 
 static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
 
-static ssize_t show_rs_window(struct device *d,
-                             struct device_attribute *attr,
-                             char *buf)
-{
-       struct iwl3945_priv *priv = d->driver_data;
-       return iwl3945_fill_rs_info(priv->hw, buf, IWL_AP_ID);
-}
-static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL);
-
 static ssize_t show_tx_power(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
@@ -7840,7 +7831,6 @@ static struct attribute *iwl3945_sysfs_entries[] = {
 #endif
        &dev_attr_power_level.attr,
        &dev_attr_retry_rate.attr,
-       &dev_attr_rs_window.attr,
        &dev_attr_statistics.attr,
        &dev_attr_status.attr,
        &dev_attr_temperature.attr,
@@ -7908,6 +7898,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        SET_IEEE80211_DEV(hw, &pdev->dev);
 
        hw->rate_control_algorithm = "iwl-3945-rs";
+       hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
 
        IWL_DEBUG_INFO("*** LOAD DRIVER ***\n");
        priv = hw->priv;
index aee19fa844e46b29531d67f66ab236b9ad4dc43c..a912fb68c09990fd12bfc18360e3d9c674b79e7f 100644 (file)
@@ -1949,7 +1949,7 @@ int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
        cmd.hdr.size = cpu_to_le16(sizeof(cmd));
        cmd.action = cpu_to_le16(CMD_ACT_SET);
        cmd.enable = !!enable;
-       cmd.usesnr = !!enable;
+       cmd.usesnr = !!usesnr;
        cmd.P0 = p0;
        cmd.P1 = p1;
        cmd.P2 = p2;
index d002160f597d6265dcef453dc9153511a5cc97cd..36be4c9703e0b0c12fd4f0ee6f4b31db56bc8fe5 100644 (file)
@@ -32,6 +32,12 @@ int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
 int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
                int8_t p2, int usesnr);
 
+int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
+               int8_t p1, int8_t p2);
+
+int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
+               int8_t p2, int usesnr);
+
 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
                     struct cmd_header *resp);
 
index 58d11a35e61b9840349f32aeccb998253e964b23..076a636e8f62165252b8f931f88312187e64c1bf 100644 (file)
@@ -189,7 +189,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 #define MRVDRV_CMD_UPLD_RDY            0x0008
 #define MRVDRV_CARDEVENT               0x0010
 
-
 /* Automatic TX control default levels */
 #define POW_ADAPT_DEFAULT_P0 13
 #define POW_ADAPT_DEFAULT_P1 15
index acb889e25900d397792b499b0fa4726bd8f843ab..f6f3753da303d80f26bc95d0f51ca52f03106814 100644 (file)
@@ -58,6 +58,7 @@ struct lbs_802_11_security {
        u8 WPA2enabled;
        u8 wep_enabled;
        u8 auth_mode;
+       u32 key_mgmt;
 };
 
 /** Current Basic Service Set State Structure */
index 11297dcf9fc3f2639fcda0014ba837877488d9b6..82c3e5a50ea695602fa844b7cc5ce93493f1b0d3 100644 (file)
@@ -1025,6 +1025,18 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info,
                                new_rate);
                        goto out;
                }
+               if (priv->fwrelease < 0x09000000) {
+                       ret = lbs_set_power_adapt_cfg(priv, 0,
+                                       POW_ADAPT_DEFAULT_P0,
+                                       POW_ADAPT_DEFAULT_P1,
+                                       POW_ADAPT_DEFAULT_P2);
+                       if (ret)
+                               goto out;
+               }
+               ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1,
+                               TPC_DEFAULT_P2, 1);
+               if (ret)
+                       goto out;
        }
 
        /* Try the newer command first (Firmware Spec 5.1 and above) */
@@ -1598,8 +1610,20 @@ static int lbs_set_encodeext(struct net_device *dev,
        }
 
 out:
-       if (ret == 0) {  /* key installation is time critical: postpone not! */
-               lbs_do_association_work(priv);
+       if (ret == 0) {
+               /* 802.1x and WPA rekeying must happen as quickly as possible,
+                * especially during the 4-way handshake; thus if in
+                * infrastructure mode, and either (a) 802.1x is enabled or
+                * (b) WPA is being used, set the key right away.
+                */
+               if (assoc_req->mode == IW_MODE_INFRA &&
+                   ((assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_802_1X) ||
+                    (assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_PSK) ||
+                     assoc_req->secinfo.WPAenabled ||
+                     assoc_req->secinfo.WPA2enabled)) {
+                       lbs_do_association_work(priv);
+               } else
+                       lbs_postpone_association_work(priv);
        } else {
                lbs_cancel_association_work(priv);
        }
@@ -1707,13 +1731,17 @@ static int lbs_set_auth(struct net_device *dev,
        case IW_AUTH_TKIP_COUNTERMEASURES:
        case IW_AUTH_CIPHER_PAIRWISE:
        case IW_AUTH_CIPHER_GROUP:
-       case IW_AUTH_KEY_MGMT:
        case IW_AUTH_DROP_UNENCRYPTED:
                /*
                 * libertas does not use these parameters
                 */
                break;
 
+       case IW_AUTH_KEY_MGMT:
+               assoc_req->secinfo.key_mgmt = dwrq->value;
+               updated = 1;
+               break;
+
        case IW_AUTH_WPA_VERSION:
                if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) {
                        assoc_req->secinfo.WPAenabled = 0;
@@ -1793,6 +1821,10 @@ static int lbs_get_auth(struct net_device *dev,
        lbs_deb_enter(LBS_DEB_WEXT);
 
        switch (dwrq->flags & IW_AUTH_INDEX) {
+       case IW_AUTH_KEY_MGMT:
+               dwrq->value = priv->secinfo.key_mgmt;
+               break;
+
        case IW_AUTH_WPA_VERSION:
                dwrq->value = 0;
                if (priv->secinfo.WPAenabled)
index f479c1af67822dfdf3813c22e8e9f60846401da7..25bae7933aa587fa22ba5b4b402c80011f3f49bf 100644 (file)
@@ -398,7 +398,7 @@ static int netwave_probe(struct pcmcia_device *link)
     link->io.IOAddrLines = 5;
     
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &netwave_interrupt;
     
index 9a2fcc0163d6ffc0a915ed0f4c560851aeae092c..50904771f2912b5d167deb38a227213204683ae8 100644 (file)
@@ -5291,7 +5291,7 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
 /* Trigger a scan (look for other cells in the vicinity) */
 static int orinoco_ioctl_setscan(struct net_device *dev,
                                 struct iw_request_info *info,
-                                struct iw_param *srq,
+                                struct iw_point *srq,
                                 char *extra)
 {
        struct orinoco_private *priv = netdev_priv(dev);
index 1ccf5a40cf06370afbf70817b0d76516e411236e..9eaa252c2430b441bf6671a9a9a354ad9bbe4c0d 100644 (file)
@@ -121,7 +121,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
        link->priv = dev;
 
        /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
        link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = orinoco_interrupt;
        link->irq.Instance = dev; 
index bac58ed03e5ca635e62b8c7522da14d05673404a..de5e8f44b20204a88365b0e8ad6f6af78a3b6c81 100644 (file)
@@ -149,7 +149,8 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                u32 code = le32_to_cpu(bootrec->code);
                switch (code) {
                case BR_CODE_COMPONENT_ID:
-                       priv->fw_interface = be32_to_cpup(bootrec->data);
+                       priv->fw_interface = be32_to_cpup((__be32 *)
+                                            bootrec->data);
                        switch (priv->fw_interface) {
                        case FW_FMAC:
                                printk(KERN_INFO "p54: FreeMAC firmware\n");
@@ -181,9 +182,8 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                        priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500;
                        priv->headroom = desc->headroom;
                        priv->tailroom = desc->tailroom;
-                       if (bootrec->len == 11)
-                               priv->rx_mtu = (size_t) le16_to_cpu(
-                                       (__le16)bootrec->data[10]);
+                       if (le32_to_cpu(bootrec->len) == 11)
+                               priv->rx_mtu = le16_to_cpu(bootrec->rx_mtu);
                        else
                                priv->rx_mtu = (size_t)
                                        0x620 - priv->tx_hdr_len;
@@ -306,11 +306,11 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
        return 0;
 }
 
-const char* p54_rf_chips[] = { "NULL", "Indigo?", "Duette",
+static const char *p54_rf_chips[] = { "NULL", "Indigo?", "Duette",
                               "Frisbee", "Xbow", "Longbow" };
 static int p54_init_xbow_synth(struct ieee80211_hw *dev);
 
-int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
+static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
 {
        struct p54_common *priv = dev->priv;
        struct eeprom_pda_wrap *wrap = NULL;
@@ -617,7 +617,7 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
        if (!priv->eeprom)
                return ;
 
-       memcpy(priv->eeprom, eeprom->data, eeprom->len);
+       memcpy(priv->eeprom, eeprom->data, le16_to_cpu(eeprom->len));
 
        complete(&priv->eeprom_comp);
 }
@@ -777,8 +777,9 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
                hdr->len = cpu_to_le16(blocksize + sizeof(*eeprom_hdr));
                eeprom_hdr->offset = cpu_to_le16(offset);
                eeprom_hdr->len = cpu_to_le16(blocksize);
-               p54_assign_address(dev, NULL, hdr, hdr->len + sizeof(*hdr));
-               priv->tx(dev, hdr, hdr->len + sizeof(*hdr), 0);
+               p54_assign_address(dev, NULL, hdr, le16_to_cpu(hdr->len) +
+                                  sizeof(*hdr));
+               priv->tx(dev, hdr, le16_to_cpu(hdr->len) + sizeof(*hdr), 0);
 
                if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
                        printk(KERN_ERR "%s: device does not respond!\n",
@@ -1247,18 +1248,20 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
 
        if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
                if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
-                       p54_set_filter(dev, priv->filter_type, NULL);
+                       p54_set_filter(dev, le16_to_cpu(priv->filter_type),
+                                NULL);
                else
-                       p54_set_filter(dev, priv->filter_type, priv->bssid);
+                       p54_set_filter(dev, le16_to_cpu(priv->filter_type),
+                                priv->bssid);
        }
 
        if (changed_flags & FIF_PROMISC_IN_BSS) {
                if (*total_flags & FIF_PROMISC_IN_BSS)
-                       p54_set_filter(dev, priv->filter_type |
-                               cpu_to_le16(0x8), NULL);
+                       p54_set_filter(dev, le16_to_cpu(priv->filter_type) |
+                               0x8, NULL);
                else
-                       p54_set_filter(dev, priv->filter_type &
-                               ~cpu_to_le16(0x8), priv->bssid);
+                       p54_set_filter(dev, le16_to_cpu(priv->filter_type) &
+                               ~0x8, priv->bssid);
        }
 }
 
index 4da736c789ac0c0125e111a9aa9f581d70f924db..2fa994cfcfed413cfdf08f9d6c043cec89b7536a 100644 (file)
@@ -18,7 +18,8 @@
 struct bootrec {
        __le32 code;
        __le32 len;
-       u32 data[0];
+       u32 data[10];
+       __le16 rx_mtu;
 } __attribute__((packed));
 
 struct bootrec_exp_if {
index 7444f37297793de7d819c1a95768ad77a90da1bb..1912f5e9a0a98aff4d67e84180307060356ab349 100644 (file)
@@ -218,17 +218,17 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data,
        usb_submit_urb(data_urb, GFP_ATOMIC);
 }
 
-__le32 p54u_lm87_chksum(const u32 *data, size_t length)
+static __le32 p54u_lm87_chksum(const u32 *data, size_t length)
 {
-       __le32 chk = 0;
+       u32 chk = 0;
 
        length >>= 2;
        while (length--) {
-               chk ^= cpu_to_le32(*data++);
+               chk ^= *data++;
                chk = (chk >> 5) ^ (chk << 3);
        }
 
-       return chk;
+       return cpu_to_le32(chk);
 }
 
 static void p54u_tx_lm87(struct ieee80211_hw *dev,
index 963960dc30f206494f9420a7cb3f799d5b931080..44da0d19b5c8d9c0ed8a96d5996e88c5d2b452fe 100644 (file)
@@ -325,7 +325,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
     p_dev->io.IOAddrLines = 5;
 
     /* Interrupt setup. For PCMCIA, driver takes what's given */
-    p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+    p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
     p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
     p_dev->irq.Handler = &ray_interrupt;
 
index 00e965b9da75b02345bf4df19b378c89b4bf88e4..2b414899dfa08107f8c2faba4be42e0aa2ffde79 100644 (file)
@@ -1627,7 +1627,6 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
 static int rndis_iw_set_scan(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct iw_param *param = &wrqu->param;
        struct usbnet *usbdev = dev->priv;
        union iwreq_data evt;
        int ret = -EINVAL;
@@ -1635,7 +1634,7 @@ static int rndis_iw_set_scan(struct net_device *dev,
 
        devdbg(usbdev, "SIOCSIWSCAN");
 
-       if (param->flags == 0) {
+       if (wrqu->data.flags == 0) {
                tmp = ccpu2(1);
                ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
                                                                sizeof(tmp));
index b686dc45483e2a4a88bf192617d6385461a6879c..f839ce044afd80a90b065afd11359d87761ddf4e 100644 (file)
@@ -1,5 +1,5 @@
-config RT2X00
-       tristate "Ralink driver support"
+menuconfig RT2X00
+       bool "Ralink driver support"
        depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
        ---help---
          This will enable the experimental support for the Ralink drivers,
@@ -17,39 +17,6 @@ config RT2X00
 
 if RT2X00
 
-config RT2X00_LIB
-       tristate
-
-config RT2X00_LIB_PCI
-       tristate
-       select RT2X00_LIB
-
-config RT2X00_LIB_USB
-       tristate
-       select RT2X00_LIB
-
-config RT2X00_LIB_FIRMWARE
-       boolean
-       depends on RT2X00_LIB
-       select FW_LOADER
-
-config RT2X00_LIB_CRYPTO
-       boolean
-       depends on RT2X00_LIB
-
-config RT2X00_LIB_RFKILL
-       boolean
-       depends on RT2X00_LIB
-       depends on RFKILL
-       default y
-
-config RT2X00_LIB_LEDS
-       boolean
-       depends on RT2X00_LIB
-       depends on NEW_LEDS
-       depends on LEDS_CLASS
-       default y
-
 config RT2400PCI
        tristate "Ralink rt2400 (PCI/PCMCIA) support"
        depends on PCI
@@ -109,6 +76,38 @@ config RT73USB
 
          When compiled as a module, this driver will be called "rt73usb.ko".
 
+config RT2X00_LIB_PCI
+       tristate
+       select RT2X00_LIB
+
+config RT2X00_LIB_USB
+       tristate
+       select RT2X00_LIB
+
+config RT2X00_LIB
+       tristate
+
+config RT2X00_LIB_FIRMWARE
+       boolean
+       select FW_LOADER
+
+config RT2X00_LIB_CRYPTO
+       boolean
+
+config RT2X00_LIB_RFKILL
+       boolean
+       default y if (RT2X00_LIB=y && RFKILL=y) || (RT2X00_LIB=m && RFKILL!=n)
+
+comment "rt2x00 rfkill support disabled due to modularized RFKILL and built-in rt2x00"
+       depends on RT2X00_LIB=y && RFKILL=m
+
+config RT2X00_LIB_LEDS
+       boolean
+       default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
+
+comment "rt2x00 leds support disabled due to modularized LEDS_CLASS and built-in rt2x00"
+       depends on RT2X00_LIB=y && LEDS_CLASS=m
+
 config RT2X00_LIB_DEBUGFS
        bool "Ralink debugfs support"
        depends on RT2X00_LIB && MAC80211_DEBUGFS
index 485c40de5cc0448f02cd93aa78790696c55cfbf2..2c6cc5c374ff3be765b681e07d17fede815a3d22 100644 (file)
@@ -543,7 +543,8 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
         * provided but key 0 is not, then the key is not found
         * by the hardware during RX).
         */
-       key->hw_key_idx = 0;
+       if (cmd == SET_KEY)
+               key->hw_key_idx = 0;
 
        if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
                set_key = rt2x00dev->ops->lib->config_pairwise_key;
index 2c36b91ff4c79da5525e6163c604fbdd22f6a65b..a461620b489f0350536bb06148e2813c609ea77f 100644 (file)
@@ -381,7 +381,7 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev,
                if (reg && reg == mask)
                        return -ENOSPC;
 
-               key->hw_key_idx += reg ? (ffz(reg) - 1) : 0;
+               key->hw_key_idx += reg ? ffz(reg) : 0;
 
                /*
                 * Upload key to hardware
@@ -477,7 +477,7 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
                                return -ENOSPC;
                }
 
-               key->hw_key_idx += reg ? (ffz(reg) - 1) : 0;
+               key->hw_key_idx += reg ? ffz(reg) : 0;
 
                /*
                 * Upload key to hardware
index 27dde3e34603705a5fdc56cdf1a5fe8fbc8debd4..934f8e03c5aae99fa9f6175d0c509d48fc245a48 100644 (file)
@@ -393,7 +393,7 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
                if (reg && reg == mask)
                        return -ENOSPC;
 
-               key->hw_key_idx += reg ? (ffz(reg) - 1) : 0;
+               key->hw_key_idx += reg ? ffz(reg) : 0;
 
                /*
                 * Upload key to hardware
@@ -494,7 +494,7 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
                                return -ENOSPC;
                }
 
-               key->hw_key_idx += reg ? (ffz(reg) - 1) : 0;
+               key->hw_key_idx += reg ? ffz(reg) : 0;
 
                /*
                 * Upload key to hardware
index e368759d1d89f8346bc06e00b675b2cda91517e3..67b26d3c3cd50548a1b4639ffb949b4345a98906 100644 (file)
@@ -195,7 +195,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
        link->priv = dev;
 
        /* Interrupt setup */
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
        link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = orinoco_interrupt;
        link->irq.Instance = dev; 
index 00a3559e5aa4c362d62b0baae8a545bd853ac3c6..b5de38a9b791bd3611678051e8d26d1d252e627b 100644 (file)
@@ -4496,7 +4496,7 @@ wavelan_probe(struct pcmcia_device *p_dev)
   p_dev->io.IOAddrLines = 3;
 
   /* Interrupt setup */
-  p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+  p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
   p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
   p_dev->irq.Handler = wavelan_interrupt;
 
index b6d4e04b8ab4765991fcf22d536349236894dbc7..74a5ad2f1223cc23c21c7e593a3f42b8ebd3e41f 100644 (file)
@@ -1917,7 +1917,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
        p_dev->io.IOAddrLines   = 5;
 
        /* Interrupt setup */
-       p_dev->irq.Attributes   = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+       p_dev->irq.Attributes   = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
        p_dev->irq.IRQInfo1     = IRQ_LEVEL_ID;
        p_dev->irq.Handler = wl3501_interrupt;
 
index a3da014f928d8b5109458ea1c6f9c48d3e21998d..fe1867b25ff7fb522e57927dfa6180f5f0f177bb 100644 (file)
@@ -611,7 +611,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr,
 
        q = &zd_hw_mac(hw)->ack_wait_queue;
        spin_lock_irqsave(&q->lock, flags);
-       for (skb = q->next; skb != (struct sk_buff *)q; skb = skb->next) {
+       skb_queue_walk(q, skb) {
                struct ieee80211_hdr *tx_hdr;
 
                tx_hdr = (struct ieee80211_hdr *)skb->data;
index da8b7433e3a69b731c5d534bb86d1f9a46bb301f..a60ae86bd5c9bddf5a9e8663ffdac0004d6183c8 100644 (file)
@@ -58,6 +58,7 @@ static struct usb_device_id usb_ids[] = {
        { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 },
        { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 },
+       { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 },
        /* ZD1211B */
        { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
        { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B },
index 40337a06c18ab7defa6160af363df122143545a9..146ca9cd1567f20858b521dc1b552c1da3362f17 100644 (file)
@@ -320,15 +320,15 @@ static int disable_slot(struct hotplug_slot *slot)
                        return -ENODEV;
                }
 
+               /* remove the device from the pci core */
+               pci_remove_bus_device(dev);
+
                /* queue work item to blow away this sysfs entry and other
                 * parts.
                 */
                INIT_WORK(&dslot->remove_work, remove_slot_worker);
                queue_work(dummyphp_wq, &dslot->remove_work);
 
-               /* blow away this sysfs entry and other parts. */
-               remove_slot(dslot);
-
                pci_dev_put(dev);
        }
        return 0;
index ab31f5ba665d14c23ba3d3f19194eb154312e9c1..9d934ddee95661b76c133864591c545bdba571cc 100644 (file)
@@ -258,7 +258,7 @@ static int pcie_poll_cmd(struct controller *ctrl)
                        return 1;
                }
        }
-       while (timeout > 1000) {
+       while (timeout > 0) {
                msleep(10);
                timeout -= 10;
                if (!pciehp_readw(ctrl, SLOTSTATUS, &slot_status)) {
index 8d0e60ac849cb5f34e609fdaf9215688091728a7..c3edcdc08e721a823b9faec718be1b58529d1fe7 100644 (file)
@@ -2348,11 +2348,34 @@ static void __init iommu_exit_mempool(void)
 
 }
 
+static int blacklist_iommu(const struct dmi_system_id *id)
+{
+       printk(KERN_INFO "%s detected; disabling IOMMU\n",
+              id->ident);
+       dmar_disabled = 1;
+       return 0;
+}
+
+static struct dmi_system_id __initdata intel_iommu_dmi_table[] = {
+       {       /* Some DG33BU BIOS revisions advertised non-existent VT-d */
+               .callback = blacklist_iommu,
+               .ident = "Intel DG33BU",
+               {       DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
+                       DMI_MATCH(DMI_BOARD_NAME, "DG33BU"),
+               }
+       },
+       { }
+};
+
+
 void __init detect_intel_iommu(void)
 {
        if (swiotlb || no_iommu || iommu_detected || dmar_disabled)
                return;
        if (early_dmar_detect()) {
+               dmi_check_system(intel_iommu_dmi_table);
+               if (dmar_disabled)
+                       return;
                iommu_detected = 1;
        }
 }
index 9a7c9e1408a41823aef2198f6e3a8e0e220d609a..851f5b83cdbc3f62f352627d0ee91848fc9923c0 100644 (file)
@@ -527,7 +527,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev)
                 */
                pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP,
                        &reg32);
-               if (!(reg32 & PCI_EXP_DEVCAP_RBER && !aspm_force)) {
+               if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) {
                        printk("Pre-1.1 PCIe device detected, "
                                "disable ASPM for %s. It can be enabled forcedly"
                                " with 'pcie_aspm=force'\n", pci_name(pdev));
index cce2f4cb1fbf37985d7303ec2e34d9f507d92aee..36698e57b97f659dbc20f03f4f6df6fe0e718694 100644 (file)
@@ -304,6 +304,9 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                } else {
                        res->start = l64;
                        res->end = l64 + sz64;
+                       printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: [%llx, %llx]\n",
+                               pci_name(dev), pos, (unsigned long long)res->start,
+                               (unsigned long long)res->end);
                }
        } else {
                sz = pci_size(l, sz, mask);
@@ -313,6 +316,9 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
 
                res->start = l;
                res->end = l + sz;
+               printk(KERN_DEBUG "PCI: %s reg %x %s: [%llx, %llx]\n", pci_name(dev),
+                       pos, (res->flags & IORESOURCE_IO) ? "io port":"32bit mmio",
+                       (unsigned long long)res->start, (unsigned long long)res->end);
        }
 
  out:
@@ -383,7 +389,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                        res->start = base;
                if (!res->end)
                        res->end = limit + 0xfff;
-               printk(KERN_INFO "PCI: bridge %s io port: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
+               printk(KERN_DEBUG "PCI: bridge %s io port: [%llx, %llx]\n",
+                       pci_name(dev), (unsigned long long) res->start,
+                       (unsigned long long) res->end);
        }
 
        res = child->resource[1];
@@ -395,7 +403,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
                res->start = base;
                res->end = limit + 0xfffff;
-               printk(KERN_INFO "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", pci_name(dev), res->start, res->end);
+               printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: [%llx, %llx]\n",
+                       pci_name(dev), (unsigned long long) res->start,
+                       (unsigned long long) res->end);
        }
 
        res = child->resource[2];
@@ -431,7 +441,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
                res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH;
                res->start = base;
                res->end = limit + 0xfffff;
-               printk(KERN_INFO "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64)?"64":"32",res->start, res->end);
+               printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n",
+                       pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32",
+                       (unsigned long long) res->start, (unsigned long long) res->end);
        }
 }
 
index 3b3b5f1787973556f7dacecd01b1ab3bbe68b68f..4edfc4731bd4296f3b33081d2f9f66946f1f231f 100644 (file)
@@ -162,7 +162,7 @@ EXPORT_SYMBOL(pci_find_slot);
  * time.
  */
 struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device,
-                               const struct pci_dev *from)
+                               struct pci_dev *from)
 {
        struct pci_dev *pdev;
 
@@ -263,7 +263,7 @@ static int match_pci_dev_by_id(struct device *dev, void *data)
  * this file.
  */
 static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
-                                        const struct pci_dev *from)
+                                        struct pci_dev *from)
 {
        struct device *dev;
        struct device *dev_start = NULL;
@@ -303,7 +303,7 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id,
  */
 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
                               unsigned int ss_vendor, unsigned int ss_device,
-                              const struct pci_dev *from)
+                              struct pci_dev *from)
 {
        struct pci_dev *pdev;
        struct pci_device_id *id;
index 1aad599816f7988ac080084dc14083b0b8a50736..3abbfad9ddab592f592001e31e3911efe002566c 100644 (file)
@@ -540,7 +540,11 @@ static void pci_bus_dump_res(struct pci_bus *bus)
                 if (!res)
                         continue;
 
-               printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", bus->number, i, (res->flags & IORESOURCE_IO)? "io port":"mmio", res->start, res->end);
+               printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n",
+                       bus->number, i,
+                       (res->flags & IORESOURCE_IO) ? "io port" : "mmio",
+                       (unsigned long long) res->start,
+                       (unsigned long long) res->end);
         }
 }
 
index 4174d9656e357f8ec5f16520ad03c86544a5e969..34c83d3ca0fac69df37ece4e352a99697ae515cd 100644 (file)
@@ -427,6 +427,18 @@ static int pcmcia_device_probe(struct device * dev)
        p_drv = to_pcmcia_drv(dev->driver);
        s = p_dev->socket;
 
+       /* The PCMCIA code passes the match data in via dev->driver_data
+        * which is an ugly hack. Once the driver probe is called it may
+        * and often will overwrite the match data so we must save it first
+        *
+        * handle pseudo multifunction devices:
+        * there are at most two pseudo multifunction devices.
+        * if we're matching against the first, schedule a
+        * call which will then check whether there are two
+        * pseudo devices, and if not, add the second one.
+        */
+       did = p_dev->dev.driver_data;
+
        ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id,
               p_drv->drv.name);
 
@@ -455,21 +467,14 @@ static int pcmcia_device_probe(struct device * dev)
                goto put_module;
        }
 
-       /* handle pseudo multifunction devices:
-        * there are at most two pseudo multifunction devices.
-        * if we're matching against the first, schedule a
-        * call which will then check whether there are two
-        * pseudo devices, and if not, add the second one.
-        */
-       did = p_dev->dev.driver_data;
        if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) &&
            (p_dev->socket->device_count == 1) && (p_dev->device_no == 0))
                pcmcia_add_device_later(p_dev->socket, 0);
 
- put_module:
+put_module:
        if (ret)
                module_put(p_drv->owner);
- put_dev:
+put_dev:
        if (ret)
                put_device(dev);
        return (ret);
index c48f3f69bdaf419f7e7394a37e081976244a99af..da3972153226a019c424ae98972ae8796e274f89 100644 (file)
@@ -748,7 +748,9 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
 
                add_timer(&skt->poll_timer);
 
-               device_create_file(&skt->socket.dev, &dev_attr_status);
+               ret = device_create_file(&skt->socket.dev, &dev_attr_status);
+               if (ret)
+                       goto out_err_8;
        }
 
        dev_set_drvdata(dev, sinfo);
@@ -758,6 +760,8 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
        do {
                skt = &sinfo->skt[i];
 
+               device_remove_file(&skt->socket.dev, &dev_attr_status);
+ out_err_8:
                del_timer_sync(&skt->poll_timer);
                pcmcia_unregister_socket(&skt->socket);
 
index e0ce65fca4e797ed2da7370093a56f1a86d04c81..9a50f245774b0491e1c31532d059049cab945c7b 100644 (file)
@@ -113,7 +113,8 @@ ccwgroup_release (struct device *dev)
 
        for (i = 0; i < gdev->count; i++) {
                if (gdev->cdev[i]) {
-                       dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
+                       if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev)
+                               dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
                        put_device(&gdev->cdev[i]->dev);
                }
        }
@@ -296,6 +297,7 @@ error:
                        if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev)
                                dev_set_drvdata(&gdev->cdev[i]->dev, NULL);
                        put_device(&gdev->cdev[i]->dev);
+                       gdev->cdev[i] = NULL;
                }
        mutex_unlock(&gdev->reg_mutex);
        put_device(&gdev->dev);
index db00b05917331b5901091f7697fa1fa2f2de8d96..f1216cf6fa8fdd098cc3bc9c145d352fb907059d 100644 (file)
@@ -423,7 +423,7 @@ int chp_new(struct chp_id chpid)
        ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group);
        if (ret) {
                device_unregister(&chp->dev);
-               goto out_free;
+               goto out;
        }
        mutex_lock(&channel_subsystems[chpid.cssid]->mutex);
        if (channel_subsystems[chpid.cssid]->cm_enabled) {
@@ -432,14 +432,15 @@ int chp_new(struct chp_id chpid)
                        sysfs_remove_group(&chp->dev.kobj, &chp_attr_group);
                        device_unregister(&chp->dev);
                        mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
-                       goto out_free;
+                       goto out;
                }
        }
        channel_subsystems[chpid.cssid]->chps[chpid.id] = chp;
        mutex_unlock(&channel_subsystems[chpid.cssid]->mutex);
-       return ret;
+       goto out;
 out_free:
        kfree(chp);
+out:
        return ret;
 }
 
index 33bff8fec7d10b0a5b02cb0ed0824cdd210b2256..326f4cc7f92c932578870443f1421488501c25c0 100644 (file)
@@ -174,6 +174,7 @@ cio_start_key (struct subchannel *sch,      /* subchannel structure */
        CIO_TRACE_EVENT(4, sch->dev.bus_id);
 
        orb = &to_io_private(sch)->orb;
+       memset(orb, 0, sizeof(union orb));
        /* sch is always under 2G. */
        orb->cmd.intparm = (u32)(addr_t)sch;
        orb->cmd.fmt = 1;
@@ -208,8 +209,10 @@ cio_start_key (struct subchannel *sch,     /* subchannel structure */
        case 1:         /* status pending */
        case 2:         /* busy */
                return -EBUSY;
-       default:                /* device/path not operational */
+       case 3:         /* device/path not operational */
                return cio_start_handle_notoper(sch, lpm);
+       default:
+               return ccode;
        }
 }
 
index 51489eff6b0b4484ad234e6b7b7a0819a6d1ddd6..1261e1a9e8cd518f78aa44754a00318182de2ad8 100644 (file)
@@ -633,6 +633,11 @@ channel_subsystem_release(struct device *dev)
 
        css = to_css(dev);
        mutex_destroy(&css->mutex);
+       if (css->pseudo_subchannel) {
+               /* Implies that it has been generated but never registered. */
+               css_subchannel_release(&css->pseudo_subchannel->dev);
+               css->pseudo_subchannel = NULL;
+       }
        kfree(css);
 }
 
@@ -785,11 +790,15 @@ init_channel_subsystem (void)
                }
                channel_subsystems[i] = css;
                ret = setup_css(i);
-               if (ret)
-                       goto out_free;
+               if (ret) {
+                       kfree(channel_subsystems[i]);
+                       goto out_unregister;
+               }
                ret = device_register(&css->device);
-               if (ret)
-                       goto out_free_all;
+               if (ret) {
+                       put_device(&css->device);
+                       goto out_unregister;
+               }
                if (css_chsc_characteristics.secm) {
                        ret = device_create_file(&css->device,
                                                 &dev_attr_cm_enable);
@@ -802,7 +811,7 @@ init_channel_subsystem (void)
        }
        ret = register_reboot_notifier(&css_reboot_notifier);
        if (ret)
-               goto out_pseudo;
+               goto out_unregister;
        css_init_done = 1;
 
        /* Enable default isc for I/O subchannels. */
@@ -810,18 +819,12 @@ init_channel_subsystem (void)
 
        for_each_subchannel(__init_channel_subsystem, NULL);
        return 0;
-out_pseudo:
-       device_unregister(&channel_subsystems[i]->pseudo_subchannel->dev);
 out_file:
-       device_remove_file(&channel_subsystems[i]->device,
-                          &dev_attr_cm_enable);
+       if (css_chsc_characteristics.secm)
+               device_remove_file(&channel_subsystems[i]->device,
+                                  &dev_attr_cm_enable);
 out_device:
        device_unregister(&channel_subsystems[i]->device);
-out_free_all:
-       kfree(channel_subsystems[i]->pseudo_subchannel->lock);
-       kfree(channel_subsystems[i]->pseudo_subchannel);
-out_free:
-       kfree(channel_subsystems[i]);
 out_unregister:
        while (i > 0) {
                struct channel_subsystem *css;
@@ -829,6 +832,7 @@ out_unregister:
                i--;
                css = channel_subsystems[i];
                device_unregister(&css->pseudo_subchannel->dev);
+               css->pseudo_subchannel = NULL;
                if (css_chsc_characteristics.secm)
                        device_remove_file(&css->device,
                                           &dev_attr_cm_enable);
index 550508df952b89693f5b13e4de5e5bec2a976ac3..84cc9ea346dbc264639d892a19e591ef7535ef8f 100644 (file)
@@ -658,6 +658,13 @@ ccw_device_offline(struct ccw_device *cdev)
 {
        struct subchannel *sch;
 
+       /* Allow ccw_device_offline while disconnected. */
+       if (cdev->private->state == DEV_STATE_DISCONNECTED ||
+           cdev->private->state == DEV_STATE_NOT_OPER) {
+               cdev->private->flags.donotify = 0;
+               ccw_device_done(cdev, DEV_STATE_NOT_OPER);
+               return 0;
+       }
        if (ccw_device_is_orphan(cdev)) {
                ccw_device_done(cdev, DEV_STATE_OFFLINE);
                return 0;
index c7ab1b864516694e97eb3438a70b26f7a20fb952..908f50b17e269cfb6159cbf84a77c06abde7d50a 100644 (file)
@@ -760,7 +760,7 @@ static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
                if (sense[SENSE_COMMAND_REJECT_BYTE] &
                    SENSE_COMMAND_REJECT_FLAG) {
                        QETH_DBF_TEXT(TRACE, 2, "CMDREJi");
-                       return 0;
+                       return 1;
                }
                if ((sense[2] == 0xaf) && (sense[3] == 0xfe)) {
                        QETH_DBF_TEXT(TRACE, 2, "AFFE");
@@ -884,6 +884,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                }
                rc = qeth_get_problem(cdev, irb);
                if (rc) {
+                       qeth_clear_ipacmd_list(card);
                        qeth_schedule_recovery(card);
                        goto out;
                }
@@ -4147,6 +4148,7 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
        unsigned long flags;
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
 
+       QETH_DBF_TEXT(SETUP, 2, "removedv");
        if (card->discipline.ccwgdriver) {
                card->discipline.ccwgdriver->remove(gdev);
                qeth_core_free_discipline(card);
index 3ac3cc1e03ccfc1ee7db35a63be8b643711036b3..955ba7a31b90606dcdaa5309d781a2a27983e2a0 100644 (file)
@@ -395,7 +395,8 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
        }
        if (card->state == CARD_STATE_SOFTSETUP) {
                qeth_l2_process_vlans(card, 1);
-               qeth_l2_del_all_mc(card);
+               if (!card->use_hard_stop)
+                       qeth_l2_del_all_mc(card);
                qeth_clear_ipacmd_list(card);
                card->state = CARD_STATE_HARDSETUP;
        }
@@ -559,7 +560,8 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card)
                        "device %s: x%x\n", CARD_BUS_ID(card), rc);
        }
 
-       if (card->info.guestlan) {
+       if ((card->info.type == QETH_CARD_TYPE_IQD) || 
+           (card->info.guestlan)) {
                rc = qeth_setadpparms_change_macaddr(card);
                if (rc) {
                        QETH_DBF_MESSAGE(2, "couldn't get MAC address on "
@@ -825,7 +827,6 @@ static int qeth_l2_open(struct net_device *dev)
        }
        card->data.state = CH_STATE_UP;
        card->state = CARD_STATE_UP;
-       card->dev->flags |= IFF_UP;
        netif_start_queue(dev);
 
        if (!card->lan_online && netif_carrier_ok(dev))
@@ -840,7 +841,6 @@ static int qeth_l2_stop(struct net_device *dev)
 
        QETH_DBF_TEXT(TRACE, 4, "qethstop");
        netif_tx_disable(dev);
-       card->dev->flags &= ~IFF_UP;
        if (card->state == CARD_STATE_UP)
                card->state = CARD_STATE_SOFTSETUP;
        return 0;
@@ -1137,9 +1137,13 @@ static int qeth_l2_recover(void *ptr)
        if (!rc)
                PRINT_INFO("Device %s successfully recovered!\n",
                           CARD_BUS_ID(card));
-       else
+       else {
+               rtnl_lock();
+               dev_close(card->dev);
+               rtnl_unlock();
                PRINT_INFO("Device %s could not be recovered!\n",
                           CARD_BUS_ID(card));
+       }
        return 0;
 }
 
index dd72c3c2016520fddfa81b943e5025d7a16f4398..99547dea44de1997eb91fd31690af0ffec89f8d9 100644 (file)
@@ -2795,7 +2795,6 @@ static int qeth_l3_open(struct net_device *dev)
                return -ENODEV;
        card->data.state = CH_STATE_UP;
        card->state = CARD_STATE_UP;
-       card->dev->flags |= IFF_UP;
        netif_start_queue(dev);
 
        if (!card->lan_online && netif_carrier_ok(dev))
@@ -2809,7 +2808,6 @@ static int qeth_l3_stop(struct net_device *dev)
 
        QETH_DBF_TEXT(TRACE, 4, "qethstop");
        netif_tx_disable(dev);
-       card->dev->flags &= ~IFF_UP;
        if (card->state == CARD_STATE_UP)
                card->state = CARD_STATE_SOFTSETUP;
        return 0;
@@ -3218,9 +3216,13 @@ static int qeth_l3_recover(void *ptr)
        if (!rc)
                PRINT_INFO("Device %s successfully recovered!\n",
                           CARD_BUS_ID(card));
-       else
+       else {
+               rtnl_lock();
+               dev_close(card->dev);
+               rtnl_unlock();
                PRINT_INFO("Device %s could not be recovered!\n",
                           CARD_BUS_ID(card));
+       }
        return 0;
 }
 
index 391dd29749f8118509bd43a19673b2d31eedc68e..51b6a05f4d12f107fca7cd6d40a1c4a186337828 100644 (file)
@@ -152,10 +152,8 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device)
  */
 static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
 {
-       struct zfcp_adapter *adapter;
+       struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev);
 
-       down(&zfcp_data.config_sema);
-       adapter = dev_get_drvdata(&ccw_device->dev);
        switch (event) {
        case CIO_GONE:
                dev_warn(&adapter->ccw_device->dev, "device gone\n");
@@ -174,8 +172,6 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
                                        89, NULL);
                break;
        }
-       zfcp_erp_wait(adapter);
-       up(&zfcp_data.config_sema);
        return 1;
 }
 
index e984469bb98bb04f6d0abc6652f3c435fc2f0c7e..56196c98c07b417f060e44dfb6c8a2dce2543e89 100644 (file)
@@ -39,18 +39,6 @@ struct zfcp_gpn_ft {
        struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS];
 };
 
-static struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *adapter,
-                                             u32 d_id)
-{
-       struct zfcp_port *port;
-
-       list_for_each_entry(port, &adapter->port_list_head, list)
-               if ((port->d_id == d_id) &&
-                   !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status))
-                       return port;
-       return NULL;
-}
-
 static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range,
                                   struct fcp_rscn_element *elem)
 {
@@ -341,12 +329,13 @@ void zfcp_test_link(struct zfcp_port *port)
 
        zfcp_port_get(port);
        retval = zfcp_fc_adisc(port);
-       if (retval == 0 || retval == -EBUSY)
+       if (retval == 0)
                return;
 
        /* send of ADISC was not possible */
        zfcp_port_put(port);
-       zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
+       if (retval != -EBUSY)
+               zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
 }
 
 static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
@@ -363,7 +352,6 @@ static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter)
                if (ret)
                        return ret;
                zfcp_erp_wait(adapter);
-               zfcp_port_put(adapter->nameserver_port);
        }
        return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
                                  &adapter->nameserver_port->status);
@@ -475,7 +463,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
        struct zfcp_adapter *adapter = ct->port->adapter;
        struct zfcp_port *port, *tmp;
        u32 d_id;
-       int ret = 0, x;
+       int ret = 0, x, last = 0;
 
        if (ct->status)
                return -EIO;
@@ -492,19 +480,24 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
        down(&zfcp_data.config_sema);
 
        /* first entry is the header */
-       for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES; x++) {
+       for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) {
                if (x % (ZFCP_GPN_FT_ENTRIES + 1))
                        acc++;
                else
                        acc = sg_virt(++sg);
 
+               last = acc->control & 0x80;
                d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 |
                       acc->port_id[2];
 
                /* skip the adapter's port and known remote ports */
-               if (acc->wwpn == fc_host_port_name(adapter->scsi_host) ||
-                    zfcp_get_port_by_did(adapter, d_id))
+               if (acc->wwpn == fc_host_port_name(adapter->scsi_host))
+                       continue;
+               port = zfcp_get_port_by_wwpn(adapter, acc->wwpn);
+               if (port) {
+                       zfcp_port_get(port);
                        continue;
+               }
 
                port = zfcp_port_enqueue(adapter, acc->wwpn,
                                         ZFCP_STATUS_PORT_DID_DID |
@@ -513,8 +506,6 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft)
                        ret = PTR_ERR(port);
                else
                        zfcp_erp_port_reopen(port, 0, 149, NULL);
-               if (acc->control & 0x80) /* last entry */
-                       break;
        }
 
        zfcp_erp_wait(adapter);
index 19c1ca913874a5c35c7e8a8d74347ff0ffed5bca..49dbeb754e5f30b5c732200adfcff8b368b9d442 100644 (file)
@@ -710,10 +710,10 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req)
 
 static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue)
 {
-       spin_lock(&queue->lock);
+       spin_lock_bh(&queue->lock);
        if (atomic_read(&queue->count))
                return 1;
-       spin_unlock(&queue->lock);
+       spin_unlock_bh(&queue->lock);
        return 0;
 }
 
@@ -722,13 +722,13 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
        long ret;
        struct zfcp_qdio_queue *req_q = &adapter->req_q;
 
-       spin_unlock(&req_q->lock);
+       spin_unlock_bh(&req_q->lock);
        ret = wait_event_interruptible_timeout(adapter->request_wq,
                                        zfcp_fsf_sbal_check(req_q), 5 * HZ);
        if (ret > 0)
                return 0;
 
-       spin_lock(&req_q->lock);
+       spin_lock_bh(&req_q->lock);
        return -EIO;
 }
 
@@ -870,14 +870,14 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter)
        volatile struct qdio_buffer_element *sbale;
        int retval = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS,
                                  ZFCP_REQ_NO_QTCB,
                                  adapter->pool.fsf_req_status_read);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -910,7 +910,7 @@ failed_buf:
        zfcp_fsf_req_free(req);
        zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL);
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return retval;
 }
 
@@ -988,7 +988,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id,
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND,
                                  req_flags, adapter->pool.fsf_req_abort);
-       if (unlikely(IS_ERR(req)))
+       if (IS_ERR(req))
                goto out;
 
        if (unlikely(!(atomic_read(&unit->status) &
@@ -1106,13 +1106,13 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
        struct zfcp_fsf_req *req;
        int ret = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC,
                                  ZFCP_REQ_AUTO_CLEANUP, pool);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                ret = PTR_ERR(req);
                goto out;
        }
@@ -1148,7 +1148,7 @@ failed_send:
        if (erp_action)
                erp_action->fsf_req = NULL;
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return ret;
 }
 
@@ -1223,7 +1223,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS,
                                  ZFCP_REQ_AUTO_CLEANUP, NULL);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                ret = PTR_ERR(req);
                goto out;
        }
@@ -1263,14 +1263,14 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
        struct zfcp_adapter *adapter = erp_action->adapter;
        int retval = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (!atomic_read(&adapter->req_q.count))
                goto out;
        req = zfcp_fsf_req_create(adapter,
                                  FSF_QTCB_EXCHANGE_CONFIG_DATA,
                                  ZFCP_REQ_AUTO_CLEANUP,
                                  adapter->pool.fsf_req_erp);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1295,7 +1295,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return retval;
 }
 
@@ -1306,13 +1306,13 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
        struct zfcp_fsf_req *req = NULL;
        int retval = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
                                  0, NULL);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1334,7 +1334,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter,
        zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
        retval = zfcp_fsf_req_send(req);
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        if (!retval)
                wait_event(req->completion_wq,
                           req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
@@ -1359,13 +1359,13 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
        if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
                return -EOPNOTSUPP;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (!atomic_read(&adapter->req_q.count))
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA,
                                  ZFCP_REQ_AUTO_CLEANUP,
                                  adapter->pool.fsf_req_erp);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1385,7 +1385,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return retval;
 }
 
@@ -1405,13 +1405,13 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
        if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT))
                return -EOPNOTSUPP;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (!atomic_read(&adapter->req_q.count))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0,
                                  NULL);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1427,7 +1427,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter,
        zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
        retval = zfcp_fsf_req_send(req);
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        if (!retval)
                wait_event(req->completion_wq,
                           req->status & ZFCP_STATUS_FSFREQ_COMPLETED);
@@ -1531,7 +1531,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
@@ -1539,7 +1539,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
                                  FSF_QTCB_OPEN_PORT_WITH_DID,
                                  ZFCP_REQ_AUTO_CLEANUP,
                                  adapter->pool.fsf_req_erp);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1562,7 +1562,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return retval;
 }
 
@@ -1603,14 +1603,14 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT,
                                  ZFCP_REQ_AUTO_CLEANUP,
                                  adapter->pool.fsf_req_erp);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1633,7 +1633,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return retval;
 }
 
@@ -1700,14 +1700,14 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT,
                                  ZFCP_REQ_AUTO_CLEANUP,
                                  adapter->pool.fsf_req_erp);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1731,7 +1731,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return retval;
 }
 
@@ -1875,14 +1875,14 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN,
                                  ZFCP_REQ_AUTO_CLEANUP,
                                  adapter->pool.fsf_req_erp);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1910,7 +1910,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return retval;
 }
 
@@ -1965,13 +1965,13 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
        struct zfcp_fsf_req *req;
        int retval = -EIO;
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN,
                                  ZFCP_REQ_AUTO_CLEANUP,
                                  adapter->pool.fsf_req_erp);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -1995,7 +1995,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action)
                erp_action->fsf_req = NULL;
        }
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
        return retval;
 }
 
@@ -2228,7 +2228,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
                                  adapter->pool.fsf_req_scsi);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = PTR_ERR(req);
                goto out;
        }
@@ -2351,7 +2351,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter,
                goto out;
        req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags,
                                  adapter->pool.fsf_req_scsi);
-       if (unlikely(IS_ERR(req)))
+       if (IS_ERR(req))
                goto out;
 
        req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT;
@@ -2417,12 +2417,12 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
                return ERR_PTR(-EINVAL);
        }
 
-       spin_lock(&adapter->req_q.lock);
+       spin_lock_bh(&adapter->req_q.lock);
        if (zfcp_fsf_req_sbal_get(adapter))
                goto out;
 
        req = zfcp_fsf_req_create(adapter, fsf_cfdc->command, 0, NULL);
-       if (unlikely(IS_ERR(req))) {
+       if (IS_ERR(req)) {
                retval = -EPERM;
                goto out;
        }
@@ -2447,7 +2447,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
        zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT);
        retval = zfcp_fsf_req_send(req);
 out:
-       spin_unlock(&adapter->req_q.lock);
+       spin_unlock_bh(&adapter->req_q.lock);
 
        if (!retval) {
                wait_event(req->completion_wq,
index d6dbd653fde9a46496de95b971d4338f9ec48035..69d632d851d9205e790c151dc6df5b352d62cd50 100644 (file)
@@ -423,9 +423,9 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter)
 
        /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
        req_q = &adapter->req_q;
-       spin_lock(&req_q->lock);
+       spin_lock_bh(&req_q->lock);
        atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
-       spin_unlock(&req_q->lock);
+       spin_unlock_bh(&req_q->lock);
 
        qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR);
 
index c7f06298bd3c09242abd800cebb1b2b7dfb3f104..4e0322b1c1ea07301f180621912cd785d8882402 100644 (file)
@@ -63,7 +63,7 @@ comment "SCSI support type (disk, tape, CD-ROM)"
 config BLK_DEV_SD
        tristate "SCSI disk support"
        depends on SCSI
-       select CRC_T10DIF
+       select CRC_T10DIF if BLK_DEV_INTEGRITY
        ---help---
          If you want to use SCSI hard disks, Fibre Channel disks,
          Serial ATA (SATA) or Parallel ATA (PATA) hard disks,
index 994da56fffed4e7c513345d86f93b3a9acd40238..708e475896b9c5f21c13047a8fafe382fa22cb68 100644 (file)
@@ -425,7 +425,7 @@ static int alua_check_sense(struct scsi_device *sdev,
                        /*
                         * LUN Not Accessible - ALUA state transition
                         */
-                       return NEEDS_RETRY;
+                       return ADD_TO_MLQUEUE;
                if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b)
                        /*
                         * LUN Not Accessible -- Target port in standby state
@@ -447,18 +447,18 @@ static int alua_check_sense(struct scsi_device *sdev,
                        /*
                         * Power On, Reset, or Bus Device Reset, just retry.
                         */
-                       return NEEDS_RETRY;
+                       return ADD_TO_MLQUEUE;
                if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) {
                        /*
                         * ALUA state changed
                         */
-                       return NEEDS_RETRY;
+                       return ADD_TO_MLQUEUE;
                }
                if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) {
                        /*
                         * Implicit ALUA state transition failed
                         */
-                       return NEEDS_RETRY;
+                       return ADD_TO_MLQUEUE;
                }
                break;
        }
@@ -490,7 +490,7 @@ static int alua_stpg(struct scsi_device *sdev, int state,
                if (!err)
                        return SCSI_DH_IO;
                err = alua_check_sense(sdev, &sense_hdr);
-               if (retry > 0 && err == NEEDS_RETRY) {
+               if (retry > 0 && err == ADD_TO_MLQUEUE) {
                        retry--;
                        goto retry;
                }
@@ -535,7 +535,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h)
                        return SCSI_DH_IO;
 
                err = alua_check_sense(sdev, &sense_hdr);
-               if (err == NEEDS_RETRY)
+               if (err == ADD_TO_MLQUEUE)
                        goto retry;
                sdev_printk(KERN_INFO, sdev,
                            "%s: rtpg sense code %02x/%02x/%02x\n",
index b9d23e9e9a44dff3ba612bd90f3fbcb3db4a1392..ef693e8412e9d14c1393ddf10478221b0cbacbf1 100644 (file)
@@ -439,7 +439,7 @@ static int clariion_check_sense(struct scsi_device *sdev,
                         * Unit Attention Code. This is the first IO
                         * to the new path, so just retry.
                         */
-                       return NEEDS_RETRY;
+                       return ADD_TO_MLQUEUE;
                break;
        }
 
@@ -514,7 +514,7 @@ retry:
                        return SCSI_DH_IO;
 
                err = clariion_check_sense(sdev, &sshdr);
-               if (retry > 0 && err == NEEDS_RETRY) {
+               if (retry > 0 && err == ADD_TO_MLQUEUE) {
                        retry--;
                        goto retry;
                }
index 2dee69da35cf67f412143dd2c5f190bffcc43cbc..6e2f130d56deb7b89b0852c94b788e5e7e7544a0 100644 (file)
@@ -551,7 +551,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
                         *
                         * Just retry and wait.
                         */
-                       return NEEDS_RETRY;
+                       return ADD_TO_MLQUEUE;
                break;
        case ILLEGAL_REQUEST:
                if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) {
@@ -568,7 +568,7 @@ static int rdac_check_sense(struct scsi_device *sdev,
                        /*
                         * Power On, Reset, or Bus Device Reset, just retry.
                         */
-                       return NEEDS_RETRY;
+                       return ADD_TO_MLQUEUE;
                break;
        }
        /* success just means we do not care what scsi-ml does */
index 45a3b93eed57aac2617617a79a449df231f51f8f..bf41887cdd655a4dfd0ecc04a4a8a91aa67bc265 100644 (file)
@@ -1834,7 +1834,6 @@ clear_risc_ints:
                WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
        }
        spin_unlock_irq(&ha->hardware_lock);
-       ha->isp_ops->enable_intrs(ha);
 
 fail:
        return ret;
index 26afe44265c794177380eea2b25433d2277761f5..6d0f0e5f282791fc6b8bc40c77c89a2db55b92dc 100644 (file)
@@ -1740,6 +1740,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
        if (ret)
                goto probe_failed;
 
+       ha->isp_ops->enable_intrs(ha);
+
        scsi_scan_host(host);
 
        qla2x00_alloc_sysfs_attr(ha);
index 4a1cf6377f6c89b7a654bf3c38e9e2ae8b1bcc4f..9053508967253b9d894efefbd81bdc1bf125e725 100644 (file)
@@ -914,6 +914,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
                                ds[i].d_count = sg_dma_len(s);
                        }
                        sg_count -= n;
+                       sg = s;
                }
        } else {
                cmd->dataseg[0].d_base = 0;
index 880051c89bde082320f7379b39adeb4e7823c12d..39ce3aba1dac5f459d668ee7ce4d15832918ec66 100644 (file)
@@ -391,7 +391,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd)
 
        case HARDWARE_ERROR:
                if (scmd->device->retry_hwerror)
-                       return NEEDS_RETRY;
+                       return ADD_TO_MLQUEUE;
                else
                        return SUCCESS;
 
index ff5d56b3ee4d5c66a6ee4ab34609fc1800cd347b..62307bd794a924c1f04d6b6822aa61dd2ef875c3 100644 (file)
@@ -852,7 +852,7 @@ static void scsi_end_bidi_request(struct scsi_cmnd *cmd)
 void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
 {
        int result = cmd->result;
-       int this_count = scsi_bufflen(cmd);
+       int this_count;
        struct request_queue *q = cmd->device->request_queue;
        struct request *req = cmd->request;
        int error = 0;
@@ -908,6 +908,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
         */
        if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL)
                return;
+       this_count = blk_rq_bytes(req);
 
        /* good_bytes = 0, or (inclusive) there were leftovers and
         * result = 0, so scsi_end_request couldn't retry.
index 84b4879cff114f8a6e709deed6e18c67966d9140..34d0de6cd51123cb42d7cda2bc4b62a2f5151c9b 100644 (file)
@@ -1080,7 +1080,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
         * PDT=1Fh none (no FDD connected to the requested logical unit)
         */
        if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) &&
-            (result[0] & 0x1f) == 0x1f) {
+           (result[0] & 0x1f) == 0x1f &&
+           !scsi_is_wlun(lun)) {
                SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
                                        "scsi scan: peripheral device type"
                                        " of 31, no device added\n"));
index 2a2bc89aba83204f331f3023424150cc1a050f99..e5e7d78564545543925fc6136c6e7c7fc994c028 100644 (file)
@@ -1875,7 +1875,6 @@ static int sd_probe(struct device *dev)
 
        dev_set_drvdata(dev, sdkp);
        add_disk(gd);
-       blk_register_filter(gd);
        sd_dif_config_host(sdkp);
 
        sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
@@ -1909,7 +1908,6 @@ static int sd_remove(struct device *dev)
        struct scsi_disk *sdkp = dev_get_drvdata(dev);
 
        device_del(&sdkp->dev);
-       blk_unregister_filter(sdkp->disk);
        del_gendisk(sdkp->disk);
        sd_shutdown(dev);
 
index 3292965bfd84272ad83450b46d7a454c588c01bb..27f5bfd1def343e205c2710a587571650026410f 100644 (file)
@@ -656,7 +656,6 @@ static int sr_probe(struct device *dev)
        dev_set_drvdata(dev, cd);
        disk->flags |= GENHD_FL_REMOVABLE;
        add_disk(disk);
-       blk_register_filter(disk);
 
        sdev_printk(KERN_DEBUG, sdev,
                    "Attached scsi CD-ROM %s\n", cd->cdi.name);
@@ -895,7 +894,6 @@ static int sr_remove(struct device *dev)
 {
        struct scsi_cd *cd = dev_get_drvdata(dev);
 
-       blk_unregister_filter(cd->disk);
        del_gendisk(cd->disk);
 
        mutex_lock(&sr_ref_mutex);
index 3a6da80b081c14405ecfdd60660470928843e84c..61fb8b6d19af77be5a9b180532725c22df68d44d 100644 (file)
@@ -131,7 +131,8 @@ struct atmel_uart_char {
 struct atmel_uart_port {
        struct uart_port        uart;           /* uart */
        struct clk              *clk;           /* uart clock */
-       unsigned short          suspended;      /* is port suspended? */
+       int                     may_wakeup;     /* cached value of device_may_wakeup for times we need to disable it */
+       u32                     backup_imr;     /* IMR saved during suspend */
        int                     break_active;   /* break being received */
 
        short                   use_dma_rx;     /* enable PDC receiver */
@@ -984,8 +985,15 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state,
                 * This is called on uart_open() or a resume event.
                 */
                clk_enable(atmel_port->clk);
+
+               /* re-enable interrupts if we disabled some on suspend */
+               UART_PUT_IER(port, atmel_port->backup_imr);
                break;
        case 3:
+               /* Back up the interrupt mask and disable all interrupts */
+               atmel_port->backup_imr = UART_GET_IMR(port);
+               UART_PUT_IDR(port, -1);
+
                /*
                 * Disable the peripheral clock for this serial port.
                 * This is called on uart_close() or a suspend event.
@@ -1475,13 +1483,12 @@ static int atmel_serial_suspend(struct platform_device *pdev,
                        cpu_relax();
        }
 
-       if (device_may_wakeup(&pdev->dev)
-           && !atmel_serial_clk_will_stop())
-               enable_irq_wake(port->irq);
-       else {
-               uart_suspend_port(&atmel_uart, port);
-               atmel_port->suspended = 1;
-       }
+       /* we can not wake up if we're running on slow clock */
+       atmel_port->may_wakeup = device_may_wakeup(&pdev->dev);
+       if (atmel_serial_clk_will_stop())
+               device_set_wakeup_enable(&pdev->dev, 0);
+
+       uart_suspend_port(&atmel_uart, port);
 
        return 0;
 }
@@ -1491,11 +1498,8 @@ static int atmel_serial_resume(struct platform_device *pdev)
        struct uart_port *port = platform_get_drvdata(pdev);
        struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
 
-       if (atmel_port->suspended) {
-               uart_resume_port(&atmel_uart, port);
-               atmel_port->suspended = 0;
-       } else
-               disable_irq_wake(port->irq);
+       uart_resume_port(&atmel_uart, port);
+       device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup);
 
        return 0;
 }
@@ -1513,6 +1517,8 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev)
        BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE));
 
        port = &atmel_ports[pdev->id];
+       port->backup_imr = 0;
+
        atmel_init_port(port, pdev);
 
        if (!atmel_use_dma_rx(&port->uart)) {
index 6a29f9330a73c72d7799a83ce66a8ecd9a7e5588..3f90f1bbbbcddb728cc026fef1a4a8824995230e 100644 (file)
 #define  UCR3_RXDSEN    (1<<6)  /* Receive status interrupt enable */
 #define  UCR3_AIRINTEN   (1<<5)  /* Async IR wake interrupt enable */
 #define  UCR3_AWAKEN    (1<<4)  /* Async wake interrupt enable */
-#define  UCR3_REF25     (1<<3)  /* Ref freq 25 MHz */
-#define  UCR3_REF30     (1<<2)  /* Ref Freq 30 MHz */
+#ifdef CONFIG_ARCH_IMX
+#define  UCR3_REF25     (1<<3)  /* Ref freq 25 MHz, only on mx1 */
+#define  UCR3_REF30     (1<<2)  /* Ref Freq 30 MHz, only on mx1 */
+#endif
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+#define  UCR3_RXDMUXSEL         (1<<2)  /* RXD Muxed Input Select, on mx2/mx3 */
+#endif
 #define  UCR3_INVT      (1<<1)  /* Inverted Infrared transmission */
 #define  UCR3_BPEN      (1<<0)  /* Preset registers enable */
 #define  UCR4_CTSTL_32   (32<<10) /* CTS trigger level (32 chars) */
@@ -445,7 +450,7 @@ static irqreturn_t imx_int(int irq, void *dev_id)
                        readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
                imx_txint(irq, dev_id);
 
-       if (sts & USR1_RTSS)
+       if (sts & USR1_RTSD)
                imx_rtsint(irq, dev_id);
 
        return IRQ_HANDLED;
@@ -598,6 +603,12 @@ static int imx_startup(struct uart_port *port)
        temp |= (UCR2_RXEN | UCR2_TXEN);
        writel(temp, sport->port.membase + UCR2);
 
+#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3
+       temp = readl(sport->port.membase + UCR3);
+       temp |= UCR3_RXDMUXSEL;
+       writel(temp, sport->port.membase + UCR3);
+#endif
+
        /*
         * Enable modem status interrupts
         */
@@ -1133,13 +1144,19 @@ static int serial_imx_probe(struct platform_device *pdev)
        if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS))
                sport->have_rtscts = 1;
 
-       if (pdata->init)
-               pdata->init(pdev);
+       if (pdata->init) {
+               ret = pdata->init(pdev);
+               if (ret)
+                       goto clkput;
+       }
 
        uart_add_one_port(&imx_reg, &sport->port);
        platform_set_drvdata(pdev, &sport->port);
 
        return 0;
+clkput:
+       clk_put(sport->clk);
+       clk_disable(sport->clk);
 unmap:
        iounmap(sport->port.membase);
 free:
index 34c7c9875681708e0fa53485bb3e0e422d43db8d..0e53354c1cfe7edbde6e47ff8ca0efcc4306be7d 100644 (file)
@@ -47,9 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
 
 #define MAX_BUSES 3
 
-#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
-#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK)
-#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0)
+#define DMA_INT_MASK           (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR)
+#define RESET_DMA_CHANNEL      (DCSR_NODESC | DMA_INT_MASK)
+#define IS_DMA_ALIGNED(x)      (((x) & 0x07) == 0)
+#define MAX_DMA_LEN            8191
 
 /*
  * for testing SSCR1 changes that require SSP restart, basically
@@ -144,7 +145,6 @@ struct driver_data {
        size_t tx_map_len;
        u8 n_bytes;
        u32 dma_width;
-       int cs_change;
        int (*write)(struct driver_data *drv_data);
        int (*read)(struct driver_data *drv_data);
        irqreturn_t (*transfer_handler)(struct driver_data *drv_data);
@@ -406,8 +406,45 @@ static void giveback(struct driver_data *drv_data)
                                        struct spi_transfer,
                                        transfer_list);
 
+       /* Delay if requested before any change in chip select */
+       if (last_transfer->delay_usecs)
+               udelay(last_transfer->delay_usecs);
+
+       /* Drop chip select UNLESS cs_change is true or we are returning
+        * a message with an error, or next message is for another chip
+        */
        if (!last_transfer->cs_change)
                drv_data->cs_control(PXA2XX_CS_DEASSERT);
+       else {
+               struct spi_message *next_msg;
+
+               /* Holding of cs was hinted, but we need to make sure
+                * the next message is for the same chip.  Don't waste
+                * time with the following tests unless this was hinted.
+                *
+                * We cannot postpone this until pump_messages, because
+                * after calling msg->complete (below) the driver that
+                * sent the current message could be unloaded, which
+                * could invalidate the cs_control() callback...
+                */
+
+               /* get a pointer to the next message, if any */
+               spin_lock_irqsave(&drv_data->lock, flags);
+               if (list_empty(&drv_data->queue))
+                       next_msg = NULL;
+               else
+                       next_msg = list_entry(drv_data->queue.next,
+                                       struct spi_message, queue);
+               spin_unlock_irqrestore(&drv_data->lock, flags);
+
+               /* see if the next and current messages point
+                * to the same chip
+                */
+               if (next_msg && next_msg->spi != msg->spi)
+                       next_msg = NULL;
+               if (!next_msg || msg->state == ERROR_STATE)
+                       drv_data->cs_control(PXA2XX_CS_DEASSERT);
+       }
 
        msg->state = NULL;
        if (msg->complete)
@@ -490,10 +527,9 @@ static void dma_transfer_complete(struct driver_data *drv_data)
        msg->actual_length += drv_data->len -
                                (drv_data->rx_end - drv_data->rx);
 
-       /* Release chip select if requested, transfer delays are
-        * handled in pump_transfers */
-       if (drv_data->cs_change)
-               drv_data->cs_control(PXA2XX_CS_DEASSERT);
+       /* Transfer delays and chip select release are
+        * handled in pump_transfers or giveback
+        */
 
        /* Move to next transfer */
        msg->state = next_transfer(drv_data);
@@ -602,10 +638,9 @@ static void int_transfer_complete(struct driver_data *drv_data)
        drv_data->cur_msg->actual_length += drv_data->len -
                                (drv_data->rx_end - drv_data->rx);
 
-       /* Release chip select if requested, transfer delays are
-        * handled in pump_transfers */
-       if (drv_data->cs_change)
-               drv_data->cs_control(PXA2XX_CS_DEASSERT);
+       /* Transfer delays and chip select release are
+        * handled in pump_transfers or giveback
+        */
 
        /* Move to next transfer */
        drv_data->cur_msg->state = next_transfer(drv_data);
@@ -840,23 +875,40 @@ static void pump_transfers(unsigned long data)
                return;
        }
 
-       /* Delay if requested at end of transfer*/
+       /* Delay if requested at end of transfer before CS change */
        if (message->state == RUNNING_STATE) {
                previous = list_entry(transfer->transfer_list.prev,
                                        struct spi_transfer,
                                        transfer_list);
                if (previous->delay_usecs)
                        udelay(previous->delay_usecs);
+
+               /* Drop chip select only if cs_change is requested */
+               if (previous->cs_change)
+                       drv_data->cs_control(PXA2XX_CS_DEASSERT);
        }
 
-       /* Check transfer length */
-       if (transfer->len > 8191)
-       {
-               dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer "
-                               "length greater than 8191\n");
-               message->status = -EINVAL;
-               giveback(drv_data);
-               return;
+       /* Check for transfers that need multiple DMA segments */
+       if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {
+
+               /* reject already-mapped transfers; PIO won't always work */
+               if (message->is_dma_mapped
+                               || transfer->rx_dma || transfer->tx_dma) {
+                       dev_err(&drv_data->pdev->dev,
+                               "pump_transfers: mapped transfer length "
+                               "of %lu is greater than %d\n",
+                               transfer->len, MAX_DMA_LEN);
+                       message->status = -EINVAL;
+                       giveback(drv_data);
+                       return;
+               }
+
+               /* warn ... we force this to PIO mode */
+               if (printk_ratelimit())
+                       dev_warn(&message->spi->dev, "pump_transfers: "
+                               "DMA disabled for transfer length %ld "
+                               "greater than %d\n",
+                               (long)drv_data->len, MAX_DMA_LEN);
        }
 
        /* Setup the transfer state based on the type of transfer */
@@ -878,7 +930,6 @@ static void pump_transfers(unsigned long data)
        drv_data->len = transfer->len & DCMD_LENGTH;
        drv_data->write = drv_data->tx ? chip->write : null_writer;
        drv_data->read = drv_data->rx ? chip->read : null_reader;
-       drv_data->cs_change = transfer->cs_change;
 
        /* Change speed and bit per word on a per transfer */
        cr0 = chip->cr0;
@@ -925,7 +976,7 @@ static void pump_transfers(unsigned long data)
                                                        &dma_thresh))
                                if (printk_ratelimit())
                                        dev_warn(&message->spi->dev,
-                                               "pump_transfer: "
+                                               "pump_transfers: "
                                                "DMA burst size reduced to "
                                                "match bits_per_word\n");
                }
@@ -939,8 +990,23 @@ static void pump_transfers(unsigned long data)
 
        message->state = RUNNING_STATE;
 
-       /* Try to map dma buffer and do a dma transfer if successful */
-       if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) {
+       /* Try to map dma buffer and do a dma transfer if successful, but
+        * only if the length is non-zero and less than MAX_DMA_LEN.
+        *
+        * Zero-length non-descriptor DMA is illegal on PXA2xx; force use
+        * of PIO instead.  Care is needed above because the transfer may
+        * have have been passed with buffers that are already dma mapped.
+        * A zero-length transfer in PIO mode will not try to write/read
+        * to/from the buffers
+        *
+        * REVISIT large transfers are exactly where we most want to be
+        * using DMA.  If this happens much, split those transfers into
+        * multiple DMA segments rather than forcing PIO.
+        */
+       drv_data->dma_mapped = 0;
+       if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN)
+               drv_data->dma_mapped = map_dma_buffers(drv_data);
+       if (drv_data->dma_mapped) {
 
                /* Ensure we have the correct interrupt handler */
                drv_data->transfer_handler = dma_transfer;
index 070c6219e2d605a617c55547984cc61548a27bf3..ac0e3e4b3c543e480028d90829c7f5606b7fde71 100644 (file)
@@ -267,16 +267,13 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
        cs->hw_mode |= SPMODE_LEN(bits_per_word);
 
        if ((mpc83xx_spi->spibrg / hz) > 64) {
+               cs->hw_mode |= SPMODE_DIV16;
                pm = mpc83xx_spi->spibrg / (hz * 64);
                if (pm > 16) {
-                       cs->hw_mode |= SPMODE_DIV16;
-                       pm /= 16;
-                       if (pm > 16) {
-                               dev_err(&spi->dev, "Requested speed is too "
-                                       "low: %d Hz. Will use %d Hz instead.\n",
-                                       hz, mpc83xx_spi->spibrg / 1024);
-                               pm = 16;
-                       }
+                       dev_err(&spi->dev, "Requested speed is too "
+                               "low: %d Hz. Will use %d Hz instead.\n",
+                               hz, mpc83xx_spi->spibrg / 1024);
+                       pm = 16;
                }
        } else
                pm = mpc83xx_spi->spibrg / (hz * 4);
@@ -315,11 +312,20 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
        if (t->bits_per_word)
                bits_per_word = t->bits_per_word;
        len = t->len;
-       if (bits_per_word > 8)
+       if (bits_per_word > 8) {
+               /* invalid length? */
+               if (len & 1)
+                       return -EINVAL;
                len /= 2;
-       if (bits_per_word > 16)
+       }
+       if (bits_per_word > 16) {
+               /* invalid length? */
+               if (len & 1)
+                       return -EINVAL;
                len /= 2;
+       }
        mpc83xx_spi->count = len;
+
        INIT_COMPLETION(mpc83xx_spi->done);
 
        /* enable rx ints */
index 98abc73c1a1d298f5431a01be4f87aec73911d9a..3eb414b84a9d5a2f82482bec675e22c969d4c224 100644 (file)
@@ -430,7 +430,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev)
 #endif
 
 MODULE_ALIAS("platform:s3c2410-spi");
-static struct platform_driver s3c24xx_spidrv = {
+static struct platform_driver s3c24xx_spi_driver = {
        .remove         = __exit_p(s3c24xx_spi_remove),
        .suspend        = s3c24xx_spi_suspend,
        .resume         = s3c24xx_spi_resume,
@@ -442,12 +442,12 @@ static struct platform_driver s3c24xx_spidrv = {
 
 static int __init s3c24xx_spi_init(void)
 {
-        return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe);
+        return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe);
 }
 
 static void __exit s3c24xx_spi_exit(void)
 {
-        platform_driver_unregister(&s3c24xx_spidrv);
+        platform_driver_unregister(&s3c24xx_spi_driver);
 }
 
 module_init(s3c24xx_spi_init);
index 87ab2443e66d405ec72d45a2da2f120d59e48f0c..0ffabf5c0b60dd9892b5b9c45e2a1d8881129108 100644 (file)
@@ -471,6 +471,7 @@ static int ssb_devices_register(struct ssb_bus *bus)
 #endif
                        break;
                case SSB_BUSTYPE_SSB:
+                       dev->dma_mask = &dev->coherent_dma_mask;
                        break;
                }
 
index 07228721cafebda10100d3a1631d16473a8a6760..0da2c25bab3b2396766e36cc41ca0140f98986c3 100644 (file)
@@ -640,14 +640,13 @@ static void usbatm_cancel_send(struct usbatm_data *instance,
 
        atm_dbg(instance, "%s entered\n", __func__);
        spin_lock_irq(&instance->sndqueue.lock);
-       for (skb = instance->sndqueue.next, n = skb->next;
-            skb != (struct sk_buff *)&instance->sndqueue;
-            skb = n, n = skb->next)
+       skb_queue_walk_safe(&instance->sndqueue, skb, n) {
                if (UDSL_SKB(skb)->atm.vcc == vcc) {
                        atm_dbg(instance, "%s: popping skb 0x%p\n", __func__, skb);
                        __skb_unlink(skb, &instance->sndqueue);
                        usbatm_pop(vcc, skb);
                }
+       }
        spin_unlock_irq(&instance->sndqueue.lock);
 
        tasklet_disable(&instance->tx_channel.tasklet);
index 8abd4e59bf4abac0bb2edcee5385894f42310e98..8ab389dca2b91c49bfdb75e900a1c5a5dde3d334 100644 (file)
@@ -1876,7 +1876,8 @@ int usb_add_hcd(struct usb_hcd *hcd,
                 * with IRQF_SHARED. As usb_hcd_irq() will always disable
                 * interrupts we can remove it here.
                 */
-               irqflags &= ~IRQF_DISABLED;
+               if (irqflags & IRQF_SHARED)
+                       irqflags &= ~IRQF_DISABLED;
 
                snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
                                hcd->driver->description, hcd->self.busnum);
index 6a5cb018383d538a2b504429183be99e112c6a5b..d99963873e37aada67583be1cc84fc219f00bbb2 100644 (file)
@@ -2683,35 +2683,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                                USB_PORT_STAT_C_ENABLE);
 #endif
 
-       /* Try to use the debounce delay for protection against
-        * port-enable changes caused, for example, by EMI.
-        */
-       if (portchange & (USB_PORT_STAT_C_CONNECTION |
-                               USB_PORT_STAT_C_ENABLE)) {
-               status = hub_port_debounce(hub, port1);
-               if (status < 0) {
-                       if (printk_ratelimit())
-                               dev_err (hub_dev, "connect-debounce failed, "
-                                               "port %d disabled\n", port1);
-                       portstatus &= ~USB_PORT_STAT_CONNECTION;
-               } else {
-                       portstatus = status;
-               }
-       }
-
        /* Try to resuscitate an existing device */
        udev = hdev->children[port1-1];
        if ((portstatus & USB_PORT_STAT_CONNECTION) && udev &&
                        udev->state != USB_STATE_NOTATTACHED) {
-
                usb_lock_device(udev);
                if (portstatus & USB_PORT_STAT_ENABLE) {
                        status = 0;             /* Nothing to do */
-               } else if (!udev->persist_enabled) {
-                       status = -ENODEV;       /* Mustn't resuscitate */
 
 #ifdef CONFIG_USB_SUSPEND
-               } else if (udev->state == USB_STATE_SUSPENDED) {
+               } else if (udev->state == USB_STATE_SUSPENDED &&
+                               udev->persist_enabled) {
                        /* For a suspended device, treat this as a
                         * remote wakeup event.
                         */
@@ -2726,7 +2708,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
 #endif
 
                } else {
-                       status = usb_reset_device(udev);
+                       status = -ENODEV;       /* Don't resuscitate */
                }
                usb_unlock_device(udev);
 
@@ -2741,6 +2723,19 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                usb_disconnect(&hdev->children[port1-1]);
        clear_bit(port1, hub->change_bits);
 
+       if (portchange & (USB_PORT_STAT_C_CONNECTION |
+                               USB_PORT_STAT_C_ENABLE)) {
+               status = hub_port_debounce(hub, port1);
+               if (status < 0) {
+                       if (printk_ratelimit())
+                               dev_err(hub_dev, "connect-debounce failed, "
+                                               "port %d disabled\n", port1);
+                       portstatus &= ~USB_PORT_STAT_CONNECTION;
+               } else {
+                       portstatus = status;
+               }
+       }
+
        /* Return now if debouncing failed or nothing is connected */
        if (!(portstatus & USB_PORT_STAT_CONNECTION)) {
 
@@ -2748,7 +2743,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1,
                if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2
                                && !(portstatus & (1 << USB_PORT_FEAT_POWER)))
                        set_port_feature(hdev, port1, USB_PORT_FEAT_POWER);
+
                if (portstatus & USB_PORT_STAT_ENABLE)
                        goto done;
                return;
index 1cfccf102a2dc9fdc9948daf4aadaf5a32c793cf..45ad556169f106270675c706d8d7ae6836d4b2ea 100644 (file)
@@ -223,7 +223,7 @@ static int dr_controller_setup(struct fsl_udc *udc)
        fsl_writel(tmp, &dr_regs->endpointlistaddr);
 
        VDBG("vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x",
-               (int)udc->ep_qh, (int)tmp,
+               udc->ep_qh, (int)tmp,
                fsl_readl(&dr_regs->endpointlistaddr));
 
        /* Config PHY interface */
index 574c53831a05fd17afd6062633aaab4843609e5f..bb54cca4c54381736ead413cec0e3747e4af9b78 100644 (file)
@@ -787,7 +787,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
                        omap_set_dma_dest_params(ep->lch,
                                OMAP_DMA_PORT_TIPB,
                                OMAP_DMA_AMODE_CONSTANT,
-                               (unsigned long) io_v2p(UDC_DATA_DMA),
+                               UDC_DATA_DMA,
                                0, 0);
                }
        } else {
@@ -804,7 +804,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel)
                        omap_set_dma_src_params(ep->lch,
                                OMAP_DMA_PORT_TIPB,
                                OMAP_DMA_AMODE_CONSTANT,
-                               (unsigned long) io_v2p(UDC_DATA_DMA),
+                               UDC_DATA_DMA,
                                0, 0);
                        /* EMIFF or SDRC */
                        omap_set_dma_dest_burst_mode(ep->lch,
index d9d53f289caf48b83001b42321e1bbaf9ca00886..8409e0705d6365c34e6db7252cc39eb60575877a 100644 (file)
@@ -145,16 +145,6 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr,
        return -ETIMEDOUT;
 }
 
-static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
-                                      u32 mask, u32 done, int usec)
-{
-       int error = handshake(ehci, ptr, mask, done, usec);
-       if (error)
-               ehci_to_hcd(ehci)->state = HC_STATE_HALT;
-
-       return error;
-}
-
 /* force HC to halt state from unknown (EHCI spec section 2.3) */
 static int ehci_halt (struct ehci_hcd *ehci)
 {
@@ -173,6 +163,22 @@ static int ehci_halt (struct ehci_hcd *ehci)
                          STS_HALT, STS_HALT, 16 * 125);
 }
 
+static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
+                                      u32 mask, u32 done, int usec)
+{
+       int error;
+
+       error = handshake(ehci, ptr, mask, done, usec);
+       if (error) {
+               ehci_halt(ehci);
+               ehci_to_hcd(ehci)->state = HC_STATE_HALT;
+               ehci_err(ehci, "force halt; handhake %p %08x %08x -> %d\n",
+                       ptr, mask, done, error);
+       }
+
+       return error;
+}
+
 /* put TDI/ARC silicon into EHCI mode */
 static void tdi_reset (struct ehci_hcd *ehci)
 {
index b7853c8bac0fb58c3c7f74e18145362b6f2002cd..4a0c5a78b2ed74358055e800d5181b1a1e2cb1c7 100644 (file)
@@ -437,6 +437,9 @@ static int enable_periodic (struct ehci_hcd *ehci)
        u32     cmd;
        int     status;
 
+       if (ehci->periodic_sched++)
+               return 0;
+
        /* did clearing PSE did take effect yet?
         * takes effect only at frame boundaries...
         */
@@ -461,6 +464,9 @@ static int disable_periodic (struct ehci_hcd *ehci)
        u32     cmd;
        int     status;
 
+       if (--ehci->periodic_sched)
+               return 0;
+
        /* did setting PSE not take effect yet?
         * takes effect only at frame boundaries...
         */
@@ -544,13 +550,10 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
                : (qh->usecs * 8);
 
        /* maybe enable periodic schedule processing */
-       if (!ehci->periodic_sched++)
-               return enable_periodic (ehci);
-
-       return 0;
+       return enable_periodic(ehci);
 }
 
-static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
+static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
        unsigned        i;
        unsigned        period;
@@ -586,9 +589,7 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh)
        qh_put (qh);
 
        /* maybe turn off periodic schedule */
-       ehci->periodic_sched--;
-       if (!ehci->periodic_sched)
-               (void) disable_periodic (ehci);
+       return disable_periodic(ehci);
 }
 
 static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh)
@@ -1562,9 +1563,7 @@ itd_link_urb (
        urb->hcpriv = NULL;
 
        timer_action (ehci, TIMER_IO_WATCHDOG);
-       if (unlikely (!ehci->periodic_sched++))
-               return enable_periodic (ehci);
-       return 0;
+       return enable_periodic(ehci);
 }
 
 #define        ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR)
@@ -1642,7 +1641,7 @@ itd_complete (
        ehci_urb_done(ehci, urb, 0);
        retval = true;
        urb = NULL;
-       ehci->periodic_sched--;
+       (void) disable_periodic(ehci);
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
        if (unlikely (list_empty (&stream->td_list))) {
@@ -1951,9 +1950,7 @@ sitd_link_urb (
        urb->hcpriv = NULL;
 
        timer_action (ehci, TIMER_IO_WATCHDOG);
-       if (!ehci->periodic_sched++)
-               return enable_periodic (ehci);
-       return 0;
+       return enable_periodic(ehci);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2019,7 +2016,7 @@ sitd_complete (
        ehci_urb_done(ehci, urb, 0);
        retval = true;
        urb = NULL;
-       ehci->periodic_sched--;
+       (void) disable_periodic(ehci);
        ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--;
 
        if (list_empty (&stream->td_list)) {
@@ -2243,8 +2240,7 @@ restart:
                        if (unlikely (modified)) {
                                if (likely(ehci->periodic_sched > 0))
                                        goto restart;
-                               /* maybe we can short-circuit this scan! */
-                               disable_periodic(ehci);
+                               /* short-circuit this scan */
                                now_uframe = clock;
                                break;
                        }
index a0017486ad4ea27f6220764ede93cb3562e59247..58b2b8fc9439c7b93b956e930e74387f17057cf3 100644 (file)
@@ -9,6 +9,7 @@ comment "Enable Host or Gadget support to see Inventra options"
 # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller
 config USB_MUSB_HDRC
        depends on (USB || USB_GADGET) && HAVE_CLK
+       depends on !SUPERH
        select TWL4030_USB if MACH_OMAP_3430SDP
        tristate 'Inventra Highspeed Dual Role Controller (TI, ...)'
        help
index c5b8f0296fcf2f9f9a7ab40404d1f8324e325508..128e949db47c4a2c64f0156a2c7c227ef8f16fd1 100644 (file)
 #include <linux/io.h>
 
 #ifdef CONFIG_ARM
-#include <asm/arch/hardware.h>
-#include <asm/arch/memory.h>
+#include <mach/hardware.h>
+#include <mach/memory.h>
 #include <asm/mach-types.h>
 #endif
 
index 298b22e6ad0dd999afaa7872fafd3babdbdfe960..9d2dcb121c5e95cc7e6ba81a5cdfa59ae07637ae 100644 (file)
@@ -35,8 +35,8 @@
 #include <linux/io.h>
 
 #include <asm/mach-types.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/mux.h>
+#include <mach/hardware.h>
+#include <mach/mux.h>
 
 #include "musb_core.h"
 #include "omap2430.h"
index 786a62071f7236382be179f2cf3116d10f2e5135..dc7670718cd2ba4bfd8aa4f080b54a2de0fe3a86 100644 (file)
@@ -11,8 +11,8 @@
 #define __MUSB_OMAP243X_H__
 
 #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430)
-#include <asm/arch/hardware.h>
-#include <asm/arch/usb.h>
+#include <mach/hardware.h>
+#include <mach/usb.h>
 
 /*
  * OMAP2430-specific definitions
index 442cba69cce5b9742aa883872122522d0e525925..1279553381e34a5d4486ded444294a533f53371c 100644 (file)
@@ -72,6 +72,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
        { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */
        { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */
+       { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
        { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
        { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
        { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
@@ -83,6 +84,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
        { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
        { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */
+       { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
        { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
        { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
@@ -93,6 +95,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
        { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
        { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
+       { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
        { } /* Terminating Entry */
 };
 
index 984f6eff4c475acb6cdfdb85407897aac9e87d01..3dc93b542b30634cd23bbbe012b16034c84f6449 100644 (file)
@@ -654,6 +654,9 @@ static struct usb_device_id id_table_combined [] = {
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
        { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
+       { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) },
+       { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
 };
index 382265bba9690b84eaf51c57b16a0e460c3f29ee..8a5b6df3a97673664b27c2ebb162076f63261685 100644 (file)
 
 #define PAPOUCH_VID                    0x5050  /* Vendor ID */
 #define PAPOUCH_TMU_PID                        0x0400  /* TMU USB Thermometer */
+#define PAPOUCH_QUIDO4x4_PID           0x0900  /* Quido 4/4 Module */
 
 /*
  * ACG Identification Technologies GmbH products (http://www.acg.de/).
 /* Rig Expert Ukraine devices */
 #define FTDI_REU_TINY_PID              0xED22  /* RigExpert Tiny */
 
+/* Domintell products  http://www.domintell.com */
+#define FTDI_DOMINTELL_DGQG_PID        0xEF50  /* Master */
+#define FTDI_DOMINTELL_DUSB_PID        0xEF51  /* DUSB01 module */
+
 /* Commands */
 #define FTDI_SIO_RESET                 0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL    1 /* Set the modem control register */
index 9f9cd36455f463423e4cbe22fd752e639415580b..73f8277f88f2d26d57dafa9604f4eae5cb0468a9 100644 (file)
@@ -218,6 +218,7 @@ static int  option_send_setup(struct tty_struct *tty, struct usb_serial_port *po
 /* ZTE PRODUCTS */
 #define ZTE_VENDOR_ID                          0x19d2
 #define ZTE_PRODUCT_MF628                      0x0015
+#define ZTE_PRODUCT_CDMA_TECH                  0xfffe
 
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
@@ -347,6 +348,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
        { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) },
        { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) },
+       { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) },
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 706033753adb7836db59e343310022e2469436e5..ea1a103c99bea9f23d3a4eb7fb4f846ccbed987f 100644 (file)
@@ -14,7 +14,7 @@
   Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
 */
 
-#define DRIVER_VERSION "v.1.2.13a"
+#define DRIVER_VERSION "v.1.3.2"
 #define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>"
 #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
 
@@ -30,9 +30,6 @@
 
 #define SWIMS_USB_REQUEST_SetPower     0x00
 #define SWIMS_USB_REQUEST_SetNmea      0x07
-#define SWIMS_USB_REQUEST_SetMode      0x0B
-#define SWIMS_USB_REQUEST_GetSwocInfo  0x0A
-#define SWIMS_SET_MODE_Modem           0x0001
 
 /* per port private data */
 #define N_IN_URB       4
@@ -163,7 +160,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
        { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
        { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */
-       { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */
+       { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */
        { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
        { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */
        { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */
@@ -175,6 +172,8 @@ static struct usb_device_id id_table [] = {
         /* Sierra Wireless Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) },
        { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */
+       { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */
+       { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */
 
        { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
        { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */
@@ -187,6 +186,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */
        { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */
        { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */
+       { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */
        { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */
        { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */
        { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */
@@ -204,6 +204,8 @@ static struct usb_device_id id_table [] = {
        /* Sierra Wireless Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)},
        /* Sierra Wireless Device */
+       { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)},
+       /* Sierra Wireless Device */
        { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
 
        { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */
index e39c779e416099ea0a94a28d622851abaf71f13a..9a3e495c769cc92f7abaa59d33d7138fe2e73f73 100644 (file)
@@ -1744,7 +1744,7 @@ static int ti_download_firmware(struct ti_device *tdev, int type)
        if (buffer) {
                memcpy(buffer, fw_p->data, fw_p->size);
                memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size);
-               ti_do_download(dev, pipe, buffer, fw_p->size);
+               status = ti_do_download(dev, pipe, buffer, fw_p->size);
                kfree(buffer);
        }
        release_firmware(fw_p);
index b157c48e8b78df594bd0386f5ff38a725cf18929..4f7f9e3ae0a43fe0fd630aaf4f436637383b0e4d 100644 (file)
@@ -733,7 +733,9 @@ int usb_serial_probe(struct usb_interface *interface,
            ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) &&
             (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) ||
            ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) &&
-            (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID))) {
+            (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID)) ||
+           ((le16_to_cpu(dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) &&
+            (le16_to_cpu(dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_EF81))) {
                if (interface != dev->actconfig->interface[0]) {
                        /* check out the endpoints of the other interface*/
                        iface_desc = dev->actconfig->interface[0]->cur_altsetting;
index c76034672c18c6c87220fc37e5913f45e95be782..3d9249632ae12e7051174817241ef37ea6f2cd4c 100644 (file)
@@ -146,18 +146,6 @@ config USB_STORAGE_KARMA
          on the resulting scsi device node returns the Karma to normal
          operation.
 
-config USB_STORAGE_SIERRA
-       bool "Sierra Wireless TRU-Install Feature Support"
-       depends on USB_STORAGE
-       help
-         Say Y here to include additional code to support Sierra Wireless
-         products with the TRU-Install feature (e.g., AC597E, AC881U).
-
-         This code switches the Sierra Wireless device from being in
-         Mass Storage mode to Modem mode. It also has the ability to
-         support host software upgrades should full Linux support be added
-         to TRU-Install.
-
 config USB_STORAGE_CYPRESS_ATACB
        bool "SAT emulation on Cypress USB/ATA Bridge with ATACB"
        depends on USB_STORAGE
index bc3415b475c9b5675d0aec6d33cf0f117d7862da..7f8beb5366aec91656787736c5c1b3f1fb0d0712 100644 (file)
@@ -21,11 +21,10 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT)      += jumpshot.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA)   += alauda.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA)    += karma.o
-usb-storage-obj-$(CONFIG_USB_STORAGE_SIERRA)   += sierra_ms.o
 usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o
 
 usb-storage-objs :=    scsiglue.o protocol.o transport.o usb.o \
-                       initializers.o $(usb-storage-obj-y)
+                       initializers.o sierra_ms.o $(usb-storage-obj-y)
 
 ifneq ($(CONFIG_USB_LIBUSUAL),)
        obj-$(CONFIG_USB)       += libusual.o
index ba412e68d474a70e13bf7b68543eeb5f32c3fad7..cd155475cb6edf9a3af0cf115ffd2aa751fb0972 100644 (file)
@@ -160,6 +160,13 @@ UNUSUAL_DEV(  0x0421, 0x0019, 0x0592, 0x0592,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_MAX_SECTORS_64 ),
 
+/* Reported by Filip Joelsson <filip@blueturtle.nu> */
+UNUSUAL_DEV(  0x0421, 0x005d, 0x0001, 0x0600,
+               "Nokia",
+               "Nokia 3110c",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY ),
+
 /* Reported by Mario Rettig <mariorettig@web.de> */
 UNUSUAL_DEV(  0x0421, 0x042e, 0x0100, 0x0100,
                "Nokia",
@@ -232,6 +239,20 @@ UNUSUAL_DEV(  0x0421, 0x04b9, 0x0551, 0x0551,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
+/* Reported by Richard Nauber <RichardNauber@web.de> */
+UNUSUAL_DEV(  0x0421, 0x04fa, 0x0601, 0x0601,
+               "Nokia",
+               "6300",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_CAPACITY ),
+
+/* Patch for Nokia 5310 capacity */
+UNUSUAL_DEV(  0x0421, 0x006a, 0x0000, 0x0591,
+       "Nokia",
+       "5310",
+       US_SC_DEVICE, US_PR_DEVICE, NULL,
+       US_FL_FIX_CAPACITY ),
+
 /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */
 UNUSUAL_DEV(  0x0424, 0x0fdc, 0x0210, 0x0210,
                "SMSC",
@@ -987,6 +1008,13 @@ UNUSUAL_DEV(  0x069b, 0x3004, 0x0001, 0x0001,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY ),
 
+/* Reported by Adrian Pilchowiec <adi1981@epf.pl> */
+UNUSUAL_DEV(  0x071b, 0x3203, 0x0000, 0x0000,
+               "RockChip",
+               "MP3",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64),
+
 /* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com>
  * This USB MP3/AVI player device fails and disconnects if more than 128
  * sectors (64kB) are read/written in a single command, and may be present
@@ -1576,7 +1604,6 @@ UNUSUAL_DEV(  0x10d6, 0x2200, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                0),
 
-#ifdef CONFIG_USB_STORAGE_SIERRA
 /* Reported by Kevin Lloyd <linux@sierrawireless.com>
  * Entry is needed for the initializer function override,
  * which instructs the device to load as a modem
@@ -1587,7 +1614,6 @@ UNUSUAL_DEV(  0x1199, 0x0fff, 0x0000, 0x9999,
                "USB MMC Storage",
                US_SC_DEVICE, US_PR_DEVICE, sierra_ms_init,
                0),
-#endif
 
 /* Reported by Jaco Kroon <jaco@kroon.co.za>
  * The usb-storage module found on the Digitech GNX4 (and supposedly other
index 73679aa506debe4a7b26cd33fd24fcbafbb6f1bf..27016fd2cad19003852154d23afc3d3f75573c9e 100644 (file)
 #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB
 #include "cypress_atacb.h"
 #endif
-#ifdef CONFIG_USB_STORAGE_SIERRA
 #include "sierra_ms.h"
-#endif
 
 /* Some informational data */
 MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>");
index 5a24c6411d3486baee17ed6d79d1bfdb4764a2aa..75dac578104f5e2808e8b4439c5a3abd4f004c66 100644 (file)
@@ -208,6 +208,36 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2)
        return value;
 }
 
+static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
+{
+       /* Turn off the LCD controller and the DMA controller */
+       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+                       sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
+
+       /* Wait for the LCDC core to become idle */
+       while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
+               msleep(10);
+
+       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+}
+
+static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo)
+{
+       atmel_lcdfb_stop_nowait(sinfo);
+
+       /* Wait for DMA engine to become idle... */
+       while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
+               msleep(10);
+}
+
+static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
+{
+       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+               (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
+               | ATMEL_LCDC_PWR);
+}
+
 static void atmel_lcdfb_update_dma(struct fb_info *info,
                               struct fb_var_screeninfo *var)
 {
@@ -420,26 +450,8 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo)
 {
        might_sleep();
 
-       /* LCD power off */
-       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
-
-       /* wait for the LCDC core to become idle */
-       while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
-               msleep(10);
-
-       /* DMA disable */
-       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
-
-       /* wait for DMA engine to become idle */
-       while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
-               msleep(10);
-
-       /* LCD power on */
-       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
-               (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
-
-       /* DMA enable */
-       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+       atmel_lcdfb_stop(sinfo);
+       atmel_lcdfb_start(sinfo);
 }
 
 /**
@@ -471,14 +483,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
                 info->var.xres, info->var.yres,
                 info->var.xres_virtual, info->var.yres_virtual);
 
-       /* Turn off the LCD controller and the DMA controller */
-       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
-
-       /* Wait for the LCDC core to become idle */
-       while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
-               msleep(10);
-
-       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+       atmel_lcdfb_stop_nowait(sinfo);
 
        if (info->var.bits_per_pixel == 1)
                info->fix.visual = FB_VISUAL_MONO01;
@@ -583,13 +588,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)
        while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
                msleep(10);
 
-       dev_dbg(info->device, "  * re-enable DMA engine\n");
-       /* ...and enable it with updated configuration */
-       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
-
-       dev_dbg(info->device, "  * re-enable LCDC core\n");
-       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
-               (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
+       atmel_lcdfb_start(sinfo);
 
        dev_dbg(info->device, "  * DONE\n");
 
@@ -1032,11 +1031,20 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)
        struct fb_info *info = platform_get_drvdata(pdev);
        struct atmel_lcdfb_info *sinfo = info->par;
 
+       /*
+        * We don't want to handle interrupts while the clock is
+        * stopped. It may take forever.
+        */
+       lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
+
        sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
        lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
        if (sinfo->atmel_lcdfb_power_control)
                sinfo->atmel_lcdfb_power_control(0);
+
+       atmel_lcdfb_stop(sinfo);
        atmel_lcdfb_stop_clock(sinfo);
+
        return 0;
 }
 
@@ -1046,9 +1054,15 @@ static int atmel_lcdfb_resume(struct platform_device *pdev)
        struct atmel_lcdfb_info *sinfo = info->par;
 
        atmel_lcdfb_start_clock(sinfo);
+       atmel_lcdfb_start(sinfo);
        if (sinfo->atmel_lcdfb_power_control)
                sinfo->atmel_lcdfb_power_control(1);
        lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);
+
+       /* Enable FIFO & DMA errors */
+       lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI
+                       | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
+
        return 0;
 }
 
index 614a5c7017b64a68022ab936281aad01c8db832b..6799a6de66fe87d1ec01499278bb9b92f5683385 100644 (file)
@@ -130,8 +130,8 @@ static ssize_t geodewdt_write(struct file *file, const char __user *data,
        return len;
 }
 
-static int geodewdt_ioctl(struct inode *inode, struct file *file,
-                               unsigned int cmd, unsigned long arg)
+static long geodewdt_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        int __user *p = argp;
@@ -198,7 +198,7 @@ static const struct file_operations geodewdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .write          = geodewdt_write,
-       .ioctl          = geodewdt_ioctl,
+       .unlocked_ioctl = geodewdt_ioctl,
        .open           = geodewdt_open,
        .release        = geodewdt_release,
 };
index b82405cfb4cd38534bac8235c8720b7382af5a05..89fcefcc8510da969bfb13a99677e4f73faf7463 100644 (file)
@@ -85,7 +85,6 @@ static void __asr_toggle(void)
 
        outb(reg & ~asr_toggle_mask, asr_write_addr);
        reg = inb(asr_read_addr);
-       spin_unlock(&asr_lock);
 }
 
 static void asr_toggle(void)
index 0ed84162437beb913a66cdf621bde5e0d2bc9a38..6d9f3d4a9987342f5900ba43200b8c447035c6d5 100644 (file)
@@ -173,8 +173,8 @@ static const struct watchdog_info ident = {
        .identity = "PNX4008 Watchdog",
 };
 
-static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file,
-                                       unsigned int cmd, unsigned long arg)
+static long pnx4008_wdt_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
 {
        int ret = -ENOTTY;
        int time;
index 6756bcb009ed9efecdd30f8d3b40bc3f76cc2892..c9c73b69c5e54d2b6bb079c8dd70c99d3ef38aa8 100644 (file)
@@ -182,8 +182,8 @@ static ssize_t rc32434_wdt_write(struct file *file, const char *data,
        return 0;
 }
 
-static int rc32434_wdt_ioctl(struct inode *inode, struct file *file,
-       unsigned int cmd, unsigned long arg)
+static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        int new_timeout;
@@ -242,7 +242,7 @@ static struct file_operations rc32434_wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
        .write          = rc32434_wdt_write,
-       .ioctl          = rc32434_wdt_ioctl,
+       .unlocked_ioctl = rc32434_wdt_ioctl,
        .open           = rc32434_wdt_open,
        .release        = rc32434_wdt_release,
 };
index 9108efa73e7da4b1adc0a929b667abe274b9cb50..bf92802f2bbe93ab19b4531610fea7d3978a7abb 100644 (file)
@@ -144,8 +144,8 @@ static int rdc321x_wdt_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int rdc321x_wdt_ioctl(struct inode *inode, struct file *file,
-                               unsigned int cmd, unsigned long arg)
+static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd,
+                               unsigned long arg)
 {
        void __user *argp = (void __user *)arg;
        unsigned int value;
@@ -204,7 +204,7 @@ static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf,
 static const struct file_operations rdc321x_wdt_fops = {
        .owner          = THIS_MODULE,
        .llseek         = no_llseek,
-       .ioctl          = rdc321x_wdt_ioctl,
+       .unlocked_ioctl = rdc321x_wdt_ioctl,
        .open           = rdc321x_wdt_open,
        .write          = rdc321x_wdt_write,
        .release        = rdc321x_wdt_release,
index db362c34958bdf42e43ad1567eba11049795abbe..191ea6302107f39624a1e185d6e6a72a685722af 100644 (file)
@@ -115,8 +115,8 @@ static int watchdog_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static ssize_t watchdog_write(struct file *file, const char *data,
-                                               size_t len, loff_t *ppos)
+static ssize_t watchdog_write(struct file *file, const char __user *data,
+                             size_t len, loff_t *ppos)
 {
        /*
         *      Refresh the timer.
@@ -133,21 +133,22 @@ static const struct watchdog_info ident = {
 };
 
 static long watchdog_ioctl(struct file *file, unsigned int cmd,
-                                                       unsigned long arg)
+                          unsigned long arg)
 {
        unsigned int new_margin;
+       int __user *int_arg = (int __user *)arg;
        int ret = -ENOTTY;
 
        switch (cmd) {
        case WDIOC_GETSUPPORT:
                ret = 0;
-               if (copy_to_user((void *)arg, &ident, sizeof(ident)))
+               if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
                        ret = -EFAULT;
                break;
 
        case WDIOC_GETSTATUS:
        case WDIOC_GETBOOTSTATUS:
-               ret = put_user(0, (int *)arg);
+               ret = put_user(0, int_arg);
                break;
 
        case WDIOC_KEEPALIVE:
@@ -156,7 +157,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
                break;
 
        case WDIOC_SETTIMEOUT:
-               ret = get_user(new_margin, (int *)arg);
+               ret = get_user(new_margin, int_arg);
                if (ret)
                        break;
 
@@ -171,7 +172,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd,
                watchdog_ping();
                /* Fall */
        case WDIOC_GETTIMEOUT:
-               ret = put_user(soft_margin, (int *)arg);
+               ret = put_user(soft_margin, int_arg);
                break;
        }
        return ret;
index d4427cb869791cd0f1b910f5371f78aefe42c626..2e15da5459cf6bd5b0e144a0fef70cccfa6549c3 100644 (file)
@@ -60,7 +60,7 @@
 
 #define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
 
-#define BALLOON_CLASS_NAME "memory"
+#define BALLOON_CLASS_NAME "xen_memory"
 
 struct balloon_stats {
        /* We aim for 'current allocation' == 'target allocation'. */
index da75a6fbc6baa1dec30fa37b6846c9b9d2e5fc88..ca8cd305ff934be128ac7bdacef662c947812989 100644 (file)
@@ -22,6 +22,7 @@ fw-external-y := $(subst ",,$(CONFIG_EXTRA_FIRMWARE))
 
 fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
 fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
+fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin
 fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin
 fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
 fw-shipped-$(CONFIG_SMCTR) += tr_smctr.bin
index 66c51b275e9e8be1891b5c6c7d3d87ead9db9645..57002cdecd42dae9d6d2bdd5b7f94e438a63b756 100644 (file)
@@ -339,3 +339,13 @@ Licence: Allegedly GPLv2+, but no source visible. Marked:
 Found in hex form in kernel source.
 
 --------------------------------------------------------------------------
+
+Driver: CASSINI - Sun Cassini
+
+File: sun/cassini.bin
+
+Licence: Unknown
+
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
diff --git a/firmware/sun/cassini.bin.ihex b/firmware/sun/cassini.bin.ihex
new file mode 100644 (file)
index 0000000..5cd7ae7
--- /dev/null
@@ -0,0 +1,143 @@
+:1000000000827E82090000000000008E8EFFCE82FA
+:1000100025FF010FCE8426FF0111CE853DDFE58649
+:1000200039B78FF87EC3C2964784F38A009747CECC
+:100030008233FF010F9646840C8104270B96468479
+:100040000C810827577E8425964784F38A049747B6
+:10005000CE8254FF010F9646840C81042638B612D6
+:1000600020842026037E8425967BD67CFE8F56BD79
+:10007000F7B6FE8F4EBDEC8EBDFAF7BDF728CE82E7
+:1000800082FF010F9646840C8104260AB612208452
+:100090002027B57E8425BDF71F7E841F964784F3F5
+:1000A0008A089747DEE1AD00CE82AFFF010F7E8464
+:1000B00025964185102606962385402706BDED002E
+:1000C0007E83A2DE42BDEB8E9624840827037E83C6
+:1000D000DF967BD67CFE8F56BDF7B6FE8F50BDEC0B
+:1000E0008EBDFAF78611C649BDE412CE82EFFF013C
+:1000F0000F9646840C81002717C649BDE491240D54
+:10010000B612208520260CCE82C1FF010F7E8425E9
+:100110007E8416FE8F52BDEC8EBDFAF7866AC64904
+:10012000BDE412CE8327FF010F9646840C81002781
+:100130000AC649BDE49125067E84257E8416B6183C
+:1001400070BB19702A0481AF2E19967BF62007FA2E
+:100150002027C4388138270BF62007FA2027CB0840
+:100160007E82D3BDF7668674C649BDE412CE837124
+:10017000FF010F9646840C8108260AC649BDE4910A
+:1001800025067E84257E8416BDF73E260EBDE50934
+:100190002606CE82C1FF010F7E8425FE8F54BDEC62
+:1001A0008EBDFAF7BDF733860FC651BDE412CE837C
+:1001B000B2FF010F9646840C8108265CB61220849B
+:1001C0003F813A271C9623854027037E8425C6510C
+:1001D000BDE49125037E8425CE82C1FF010F7E847C
+:1001E00025BDF8377C007ACE83EEFF010F7E842593
+:1001F0009646840C81082620962484082629B61861
+:1002000082BB1982B1013B2209B6122084378132A8
+:100210002715BDF8447E82C1BDF71FBDF844BDFC63
+:1002200029CE8225FF010F39964784FC8A00974723
+:10023000CE8434FF011196468403810227037E8514
+:100240001E964784FC8A029747DEE1AD008601B71F
+:100250001251BDF714B6103184FDB71031BDF81E30
+:100260009681D682FE8F5ABDF7B6FE8F5CBDEC8EAE
+:10027000BDFAF78608D600C51026028B20C651BDF0
+:10028000E412CE8486FF011196468403810227037F
+:100290007E850FC651BDE49125037E851E9644855B
+:1002A00010260AB61250BA013C851027A8BDF76681
+:1002B000CE84B7FF01117E851E96468403810226F7
+:1002C00050B612308403810127037E851E96448533
+:1002D000102613B61250BA013C85102609CE84535D
+:1002E000FF01117E851EB610318A02B71031BD851F
+:1002F0001FBDF8377C0080CE84FEFF01117E851E75
+:100300009646840381022609B612308403810127B0
+:100310000FBDF844BDF70BBDFC29CE8426FF0111AB
+:1003200039D622C40FB61230BA12328404270D9681
+:100330002285042705CA107E853ACA20D72239862D
+:1003400000978318CE1C00BDEB4696578501270207
+:100350004F3985022701397F8F7D8604B7120486C5
+:1003600008B712078610B7120C8607B71206B68FA9
+:100370007DB712708601BA1204B71204010101019F
+:100380000101B6120484FE8A02B7120401010101C0
+:10039000010186FDB41204B71204B612008408816C
+:1003A000082716B68F7D810C27088B04B78F7D7EBA
+:1003B000856C860397407E896E8607B712065FF7C5
+:1003C0008F825FF78F7FF78F70F78F71F78F72F7DC
+:1003D0008F73F78F74F78F75F78F76F78F77F78FA7
+:1003E00078F78F79F78F7AF78F7BB612048A10B778
+:1003F000120486E4B71270B71207F71205F7120954
+:100400008608BA1204B7120486F7B41204B71204AD
+:10041000010101010101B61208277F8180260B86A8
+:1004200008CE8F79BD897B7E868E8140260B86041F
+:10043000CE8F76BD897B7E868E8120260B8602CE6E
+:100440008F73BD897B7E868E8110260B8601CE8FB1
+:1004500070BD897B7E868E8108260B8608CE8F79BB
+:10046000BD897F7E868E8104260B8604CE8F76BD65
+:10047000897F7E868E8102260B8A02CE8F73BD898C
+:100480007F7E868E810126088601CE8F70BD897F92
+:10049000B68F7F810F26037E8747B61209840381BA
+:1004A0000327067C12097E85FEB6120684078107A3
+:1004B00027088B01B712067E86D5B68F82260A7C66
+:1004C0008F824FB712067E85C0B61206843F813FE9
+:1004D00027108B08B71206B6120984FCB712097EE2
+:1004E00085FECE8F7018CE8F84C60CBD896FCE8FDF
+:1004F0008418CE8F70C60CBD896FD683C14F2D0373
+:100500007E8740B68F7F8107270F810B2715810DCE
+:10051000271B810E27217E8740F78F7B8602B78FAE
+:100520007A201CF78F788602B78F772012F78F75A5
+:100530008602B78F742008F78F728602B78F717E9C
+:100540008747860497407E896ECE8F72BD89F7CE2D
+:100550008F75BD89F7CE8F78BD89F7CE8F7BBD892A
+:10056000F74FB78F7DB78F81B68F7227477C8F7D0E
+:10057000B68F75273F7C8F7DB68F7827377C8F7D30
+:10058000B68F7B272F7F8F7D7C8F817A8F72271B81
+:100590007C8F7D7A8F7527167C8F7D7A8F782711D7
+:1005A0007C8F7D7A8F7B270C7E87837A8F757A8FFD
+:1005B000787A8F7BCEC1FCF68F7D3AA600B7127099
+:1005C000B68F7226037E87FAB68F75260A18CE8FED
+:1005D00073BD89D57E87FAB68F78260A18CE8F76B6
+:1005E000BD89D57E87FAB68F7B260A18CE8F79BD56
+:1005F00089D57E87FA860597407E8900B68F7581FA
+:10060000072EF2F61206C4F81BB71206B68F7881D1
+:10061000072EE2484848F61206C4C71BB71206B6B2
+:100620008F7B81072ECFF61205C4F81BB712058603
+:1006300000F68F71BD89948601F68F74BD8994860A
+:1006400002F68F77BD89948603F68F7ABD8994CEA2
+:100650008F70A60181012707810327037E8866A684
+:1006600000B88F818401260B8C8F792C0E08080826
+:100670007E8850B612048A40B71204B6120484FB76
+:1006800084EFB71204B6120736B68F7C4848B7120B
+:10069000078601BA1204B7120401010101010186A3
+:1006A000FEB41204B712048602BA1204B71204860A
+:1006B000FDB41204B7120432B71207B61200840850
+:1006C0008108270F7C82082607867697407E896EF0
+:1006D0007E86ECB68F7F810F273CBDE6C7B7120D33
+:1006E000BDE6CBB612048A20B71204CEFFFFB612C5
+:1006F00000810C26050926F6271CB6120484DFB7F4
+:100700001204968381072C057C0083200696838B38
+:100710000897837E85417F8F7E8680B7120C860185
+:10072000B78F7DB6120C847FB7120C8A80B7120C7B
+:10073000860ABD8A06B6120A2A09B6120CBA8F7D3D
+:10074000B7120CB68F7E8160271A8B20B78F7EB6CA
+:10075000120C849FBA8F7EB7120CB68F7D48B78F6C
+:100760007D7E8921B612048A20B71204BD8A0A4F01
+:1007700039A60018A7000818085A26F539366C0063
+:1007800032BA8F7FB78F7FB612098403A701B612E2
+:1007900006843FA70239368603B78F8032C1002610
+:1007A00006B78F7C7E89C9C1012718C102270CC1F9
+:1007B000032700F68F800505F78F80F68F800505EB
+:1007C000F78F80F68F800505F78F80F68F8053F4C2
+:1007D00012071BB7120739CE8F70A60018E6001853
+:1007E000A700E700A60118E60118A701E701A60285
+:1007F00018E60218A702E70239A6008407E600C43B
+:10080000385454541BA700394A26FD399622840FC8
+:1008100097228601B78F70B61207B78F71F6120C48
+:10082000C40FC80FF78F72F68F72B68F71840327CB
+:10083000148101271C81022724F48F70272A962215
+:100840008A807E8A64F48F70271E96228A107E8AA0
+:1008500064F48F70271296228A207E8A64F48F7047
+:10086000270696228A409722748F71748F71788F31
+:1008700070B68F70851027AFD622C41058B612708C
+:1008800081E4273681E1260C96228420441BD6225F
+:10089000C4CF20235881C6260D9622844044441B91
+:1008A000D622C4AF2011588127260F962284804477
+:1008B00044441BD622C46F1B972239270C7C820626
+:0D08C000BDD9EDB682077E8AB97F82063968
+:00000001FF
+/* firmware patch for NS_DP83065 */
index c95295c65045a3540959b0ddb9c227e1366472f3..e83aa5ebe861d2a8454985875d4f74a6736291a2 100644 (file)
@@ -626,8 +626,7 @@ static struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
        return NULL;
 
 error:
-       if (fid)
-               p9_client_clunk(fid);
+       p9_client_clunk(fid);
 
        return ERR_PTR(result);
 }
index 87ee5ccee3489970b86231a3acfa1052862136db..ed8feb052df978fff85f0edaabee9fa17ce9609d 100644 (file)
@@ -125,8 +125,8 @@ static int bfs_create(struct inode *dir, struct dentry *dentry, int mode,
                                                        inode->i_ino);
        if (err) {
                inode_dec_link_count(inode);
-               iput(inode);
                mutex_unlock(&info->bfs_lock);
+               iput(inode);
                return err;
        }
        mutex_unlock(&info->bfs_lock);
index 80e93956aced2e98f2ebe8053d126d104e860ba9..e7a1a99b7464ef442a8af4ed20b0d45a4db25a65 100644 (file)
@@ -1395,6 +1395,10 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
                if (dentry->d_parent != parent)
                        goto next;
 
+               /* non-existing due to RCU? */
+               if (d_unhashed(dentry))
+                       goto next;
+
                /*
                 * It is safe to compare names since d_move() cannot
                 * change the qstr (protected by d_lock).
@@ -1410,10 +1414,8 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
                                goto next;
                }
 
-               if (!d_unhashed(dentry)) {
-                       atomic_inc(&dentry->d_count);
-                       found = dentry;
-               }
+               atomic_inc(&dentry->d_count);
+               found = dentry;
                spin_unlock(&dentry->d_lock);
                break;
 next:
index 32993beecbe91a10670cc4f5a9a72a5faf813c56..cecee501ce78805c32c9d007c658fce1e87b0a97 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -752,11 +752,11 @@ static int exec_mmap(struct mm_struct *mm)
        tsk->active_mm = mm;
        activate_mm(active_mm, mm);
        task_unlock(tsk);
-       mm_update_next_owner(old_mm);
        arch_pick_mmap_layout(mm);
        if (old_mm) {
                up_read(&old_mm->mmap_sem);
                BUG_ON(active_mm != old_mm);
+               mm_update_next_owner(old_mm);
                mmput(old_mm);
                return 0;
        }
index 506c24fb5078fe859a8b816e89239c7bb8818d4e..a53da1466277abd843b0117f89df9850423ba92b 100644 (file)
@@ -594,7 +594,7 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
                goto bail;
        }
 
-       if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)) && !p_blkno) {
+       if (!ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)) && !p_blkno && create) {
                ocfs2_error(inode->i_sb,
                            "Inode %llu has a hole at block %llu\n",
                            (unsigned long long)OCFS2_I(inode)->ip_blkno,
index 7d6b34e201db4a8ba08525f942399eb742a57731..ecc3330972e5a2de1ca8e397e3a9a0d90aec2ce8 100644 (file)
@@ -499,9 +499,9 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
                if (!size)
                        continue;
                if (from + size > get_capacity(disk)) {
-                       printk(KERN_ERR " %s: p%d exceeds device capacity\n",
+                       printk(KERN_WARNING
+                               "%s: p%d exceeds device capacity\n",
                                disk->disk_name, p);
-                       continue;
                }
                res = add_partition(disk, p, from, size, state->parts[p].flags);
                if (res) {
index bca0f81eb6876fba681f3db8dedd9788887e93b5..7821589a17d58748f9143108be13bbcd1de9dc97 100644 (file)
@@ -547,8 +547,8 @@ static int proc_register(struct proc_dir_entry * dir, struct proc_dir_entry * dp
 
        for (tmp = dir->subdir; tmp; tmp = tmp->next)
                if (strcmp(tmp->name, dp->name) == 0) {
-                       printk(KERN_WARNING "proc_dir_entry '%s' already "
-                                       "registered\n", dp->name);
+                       printk(KERN_WARNING "proc_dir_entry '%s/%s' already registered\n",
+                               dir->name, dp->name);
                        dump_stack();
                        break;
                }
index 00f10a2dcf1239d0b72b48a62d8265a0a59b3d78..29e20c6b1f7f75bd9d29de8589648985bad5f4a3 100644 (file)
@@ -183,6 +183,9 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                "SReclaimable: %8lu kB\n"
                "SUnreclaim:   %8lu kB\n"
                "PageTables:   %8lu kB\n"
+#ifdef CONFIG_QUICKLIST
+               "Quicklists:   %8lu kB\n"
+#endif
                "NFS_Unstable: %8lu kB\n"
                "Bounce:       %8lu kB\n"
                "WritebackTmp: %8lu kB\n"
@@ -190,8 +193,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                "Committed_AS: %8lu kB\n"
                "VmallocTotal: %8lu kB\n"
                "VmallocUsed:  %8lu kB\n"
-               "VmallocChunk: %8lu kB\n"
-               "Quicklists:   %8lu kB\n",
+               "VmallocChunk: %8lu kB\n",
                K(i.totalram),
                K(i.freeram),
                K(i.bufferram),
@@ -216,6 +218,9 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                K(global_page_state(NR_SLAB_RECLAIMABLE)),
                K(global_page_state(NR_SLAB_UNRECLAIMABLE)),
                K(global_page_state(NR_PAGETABLE)),
+#ifdef CONFIG_QUICKLIST
+               K(quicklist_total_size()),
+#endif
                K(global_page_state(NR_UNSTABLE_NFS)),
                K(global_page_state(NR_BOUNCE)),
                K(global_page_state(NR_WRITEBACK_TEMP)),
@@ -223,8 +228,7 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
                K(committed),
                (unsigned long)VMALLOC_TOTAL >> 10,
                vmi.used >> 10,
-               vmi.largest_chunk >> 10,
-               K(quicklist_total_size())
+               vmi.largest_chunk >> 10
                );
 
                len += hugetlb_report_meminfo(page + len);
index 1540981574738e45b4585c27d9cf5a8f43df21c9..73db464cd08b7a213365c0331824ce478a69e4d1 100644 (file)
@@ -302,18 +302,6 @@ long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs)
        int subtract_lebs;
        long long available;
 
-       /*
-        * Force the amount available to the total size reported if the used
-        * space is zero.
-        */
-       if (c->lst.total_used <= UBIFS_INO_NODE_SZ &&
-           c->budg_data_growth + c->budg_dd_growth == 0) {
-               /* Do the same calculation as for c->block_cnt */
-               available = c->main_lebs - 2;
-               available *= c->leb_size - c->dark_wm;
-               return available;
-       }
-
        available = c->main_bytes - c->lst.total_used;
 
        /*
@@ -714,34 +702,106 @@ void ubifs_release_dirty_inode_budget(struct ubifs_info *c,
 }
 
 /**
- * ubifs_budg_get_free_space - return amount of free space.
+ * ubifs_reported_space - calculate reported free space.
+ * @c: the UBIFS file-system description object
+ * @free: amount of free space
+ *
+ * This function calculates amount of free space which will be reported to
+ * user-space. User-space application tend to expect that if the file-system
+ * (e.g., via the 'statfs()' call) reports that it has N bytes available, they
+ * are able to write a file of size N. UBIFS attaches node headers to each data
+ * node and it has to write indexind nodes as well. This introduces additional
+ * overhead, and UBIFS it has to report sligtly less free space to meet the
+ * above expectetion.
+ *
+ * This function assumes free space is made up of uncompressed data nodes and
+ * full index nodes (one per data node, tripled because we always allow enough
+ * space to write the index thrice).
+ *
+ * Note, the calculation is pessimistic, which means that most of the time
+ * UBIFS reports less space than it actually has.
+ */
+long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free)
+{
+       int divisor, factor, f;
+
+       /*
+        * Reported space size is @free * X, where X is UBIFS block size
+        * divided by UBIFS block size + all overhead one data block
+        * introduces. The overhead is the node header + indexing overhead.
+        *
+        * Indexing overhead calculations are based on the following formula:
+        * I = N/(f - 1) + 1, where I - number of indexing nodes, N - number
+        * of data nodes, f - fanout. Because effective UBIFS fanout is twice
+        * as less than maximum fanout, we assume that each data node
+        * introduces 3 * @c->max_idx_node_sz / (@c->fanout/2 - 1) bytes.
+        * Note, the multiplier 3 is because UBIFS reseves thrice as more space
+        * for the index.
+        */
+       f = c->fanout > 3 ? c->fanout >> 1 : 2;
+       factor = UBIFS_BLOCK_SIZE;
+       divisor = UBIFS_MAX_DATA_NODE_SZ;
+       divisor += (c->max_idx_node_sz * 3) / (f - 1);
+       free *= factor;
+       do_div(free, divisor);
+       return free;
+}
+
+/**
+ * ubifs_get_free_space - return amount of free space.
  * @c: UBIFS file-system description object
  *
- * This function returns amount of free space on the file-system.
+ * This function calculates amount of free space to report to user-space.
+ *
+ * Because UBIFS may introduce substantial overhead (the index, node headers,
+ * alighment, wastage at the end of eraseblocks, etc), it cannot report real
+ * amount of free flash space it has (well, because not all dirty space is
+ * reclamable, UBIFS does not actually know the real amount). If UBIFS did so,
+ * it would bread user expectetion about what free space is. Users seem to
+ * accustomed to assume that if the file-system reports N bytes of free space,
+ * they would be able to fit a file of N bytes to the FS. This almost works for
+ * traditional file-systems, because they have way less overhead than UBIFS.
+ * So, to keep users happy, UBIFS tries to take the overhead into account.
  */
-long long ubifs_budg_get_free_space(struct ubifs_info *c)
+long long ubifs_get_free_space(struct ubifs_info *c)
 {
-       int min_idx_lebs, rsvd_idx_lebs;
+       int min_idx_lebs, rsvd_idx_lebs, lebs;
        long long available, outstanding, free;
 
-       /* Do exactly the same calculations as in 'do_budget_space()' */
        spin_lock(&c->space_lock);
        min_idx_lebs = ubifs_calc_min_idx_lebs(c);
+       outstanding = c->budg_data_growth + c->budg_dd_growth;
 
-       if (min_idx_lebs > c->lst.idx_lebs)
-               rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs;
-       else
-               rsvd_idx_lebs = 0;
-
-       if (rsvd_idx_lebs > c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt
-                               - c->lst.taken_empty_lebs) {
+       /*
+        * Force the amount available to the total size reported if the used
+        * space is zero.
+        */
+       if (c->lst.total_used <= UBIFS_INO_NODE_SZ && !outstanding) {
                spin_unlock(&c->space_lock);
-               return 0;
+               return (long long)c->block_cnt << UBIFS_BLOCK_SHIFT;
        }
 
        available = ubifs_calc_available(c, min_idx_lebs);
-       outstanding = c->budg_data_growth + c->budg_dd_growth;
-       c->min_idx_lebs = min_idx_lebs;
+
+       /*
+        * When reporting free space to user-space, UBIFS guarantees that it is
+        * possible to write a file of free space size. This means that for
+        * empty LEBs we may use more precise calculations than
+        * 'ubifs_calc_available()' is using. Namely, we know that in empty
+        * LEBs we would waste only @c->leb_overhead bytes, not @c->dark_wm.
+        * Thus, amend the available space.
+        *
+        * Note, the calculations below are similar to what we have in
+        * 'do_budget_space()', so refer there for comments.
+        */
+       if (min_idx_lebs > c->lst.idx_lebs)
+               rsvd_idx_lebs = min_idx_lebs - c->lst.idx_lebs;
+       else
+               rsvd_idx_lebs = 0;
+       lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
+              c->lst.taken_empty_lebs;
+       lebs -= rsvd_idx_lebs;
+       available += lebs * (c->dark_wm - c->leb_overhead);
        spin_unlock(&c->space_lock);
 
        if (available > outstanding)
index b9cb77473758563314980e00c5144a84c9ccfdaf..d7f7645779f2bab707af9c0a38e96288fe65bebf 100644 (file)
@@ -538,7 +538,7 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
                printk(KERN_DEBUG "\t%d orphan inode numbers:\n", n);
                for (i = 0; i < n; i++)
                        printk(KERN_DEBUG "\t  ino %llu\n",
-                              le64_to_cpu(orph->inos[i]));
+                              (unsigned long long)le64_to_cpu(orph->inos[i]));
                break;
        }
        default:
index 5c96f1fb70166dbd75217692722d9e727be1d031..526c01ec80032be9205e6057c48f9188b136b6e8 100644 (file)
@@ -426,7 +426,7 @@ static int ubifs_readdir(struct file *file, void *dirent, filldir_t filldir)
 
        while (1) {
                dbg_gen("feed '%s', ino %llu, new f_pos %#x",
-                       dent->name, le64_to_cpu(dent->inum),
+                       dent->name, (unsigned long long)le64_to_cpu(dent->inum),
                        key_hash_flash(c, &dent->key));
                ubifs_assert(dent->ch.sqnum > ubifs_inode(dir)->creat_sqnum);
 
@@ -587,7 +587,6 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
        if (err) {
                if (err != -ENOSPC)
                        return err;
-               err = 0;
                budgeted = 0;
        }
 
index 4071d1cae29f7cb0b65221ecd541b3832b37be31..3d698e2022b1ee7b2c8250fc75c89fff79785097 100644 (file)
@@ -793,7 +793,7 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
        int err;
        struct ubifs_budget_req req;
        loff_t old_size = inode->i_size, new_size = attr->ia_size;
-       int offset = new_size & (UBIFS_BLOCK_SIZE - 1);
+       int offset = new_size & (UBIFS_BLOCK_SIZE - 1), budgeted = 1;
        struct ubifs_inode *ui = ubifs_inode(inode);
 
        dbg_gen("ino %lu, size %lld -> %lld", inode->i_ino, old_size, new_size);
@@ -811,8 +811,15 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
        /* A funny way to budget for truncation node */
        req.dirtied_ino_d = UBIFS_TRUN_NODE_SZ;
        err = ubifs_budget_space(c, &req);
-       if (err)
-               return err;
+       if (err) {
+               /*
+                * Treat truncations to zero as deletion and always allow them,
+                * just like we do for '->unlink()'.
+                */
+               if (new_size || err != -ENOSPC)
+                       return err;
+               budgeted = 0;
+       }
 
        err = vmtruncate(inode, new_size);
        if (err)
@@ -869,7 +876,12 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode,
        err = ubifs_jnl_truncate(c, inode, old_size, new_size);
        mutex_unlock(&ui->ui_mutex);
 out_budg:
-       ubifs_release_budget(c, &req);
+       if (budgeted)
+               ubifs_release_budget(c, &req);
+       else {
+               c->nospace = c->nospace_rp = 0;
+               smp_wmb();
+       }
        return err;
 }
 
index adee7b5ddeabb6cb63769f1cfcd4b68ba959e40c..47814cde24076ba1fdd3775824d0bdeda61f79a3 100644 (file)
@@ -211,14 +211,8 @@ static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c,
  * dirty index heap, and it falls-back to LPT scanning if the heaps are empty
  * or do not have an LEB which satisfies the @min_space criteria.
  *
- * Note:
- *   o LEBs which have less than dead watermark of dirty space are never picked
- *   by this function;
- *
- * Returns zero and the LEB properties of
- * found dirty LEB in case of success, %-ENOSPC if no dirty LEB was found and a
- * negative error code in case of other failures. The returned LEB is marked as
- * "taken".
+ * Note, LEBs which have less than dead watermark of free + dirty space are
+ * never picked by this function.
  *
  * The additional @pick_free argument controls if this function has to return a
  * free or freeable LEB if one is present. For example, GC must to set it to %1,
@@ -231,6 +225,10 @@ static const struct ubifs_lprops *scan_for_dirty(struct ubifs_info *c,
  *
  * In addition @pick_free is set to %2 by the recovery process in order to
  * recover gc_lnum in which case an index LEB must not be returned.
+ *
+ * This function returns zero and the LEB properties of found dirty LEB in case
+ * of success, %-ENOSPC if no dirty LEB was found and a negative error code in
+ * case of other failures. The returned LEB is marked as "taken".
  */
 int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
                         int min_space, int pick_free)
@@ -245,7 +243,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
                int lebs, rsvd_idx_lebs = 0;
 
                spin_lock(&c->space_lock);
-               lebs = c->lst.empty_lebs;
+               lebs = c->lst.empty_lebs + c->idx_gc_cnt;
                lebs += c->freeable_cnt - c->lst.taken_empty_lebs;
 
                /*
@@ -317,7 +315,7 @@ int ubifs_find_dirty_leb(struct ubifs_info *c, struct ubifs_lprops *ret_lp,
                lp = idx_lp;
 
        if (lp) {
-               ubifs_assert(lp->dirty >= c->dead_wm);
+               ubifs_assert(lp->free + lp->dirty >= c->dead_wm);
                goto found;
        }
 
@@ -509,7 +507,6 @@ int ubifs_find_free_space(struct ubifs_info *c, int min_space, int *free,
                rsvd_idx_lebs = 0;
        lebs = c->lst.empty_lebs + c->freeable_cnt + c->idx_gc_cnt -
               c->lst.taken_empty_lebs;
-       ubifs_assert(lebs + c->lst.idx_lebs >= c->min_idx_lebs);
        if (rsvd_idx_lebs < lebs)
                /*
                 * OK to allocate an empty LEB, but we still don't want to go
index d0f3dac2908133f1ea7398d8bac29ffbd5eaa8a8..02aba36fe3d4994ac6dbdba97d0705371cd8bf21 100644 (file)
@@ -334,15 +334,21 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
 
                err = move_nodes(c, sleb);
                if (err)
-                       goto out;
+                       goto out_inc_seq;
 
                err = gc_sync_wbufs(c);
                if (err)
-                       goto out;
+                       goto out_inc_seq;
 
                err = ubifs_change_one_lp(c, lnum, c->leb_size, 0, 0, 0, 0);
                if (err)
-                       goto out;
+                       goto out_inc_seq;
+
+               /* Allow for races with TNC */
+               c->gced_lnum = lnum;
+               smp_wmb();
+               c->gc_seq += 1;
+               smp_wmb();
 
                if (c->gc_lnum == -1) {
                        c->gc_lnum = lnum;
@@ -363,6 +369,14 @@ int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp)
 out:
        ubifs_scan_destroy(sleb);
        return err;
+
+out_inc_seq:
+       /* We may have moved at least some nodes so allow for races with TNC */
+       c->gced_lnum = lnum;
+       smp_wmb();
+       c->gc_seq += 1;
+       smp_wmb();
+       goto out;
 }
 
 /**
index 87dabf9fe742ea05674ec8cb2bf78f5fe98f510d..4c12a9215d7f24571d13603a382179bb223a1b40 100644 (file)
@@ -283,38 +283,6 @@ static inline void *ubifs_idx_key(const struct ubifs_info *c,
        return (void *)((struct ubifs_branch *)idx->branches)->key;
 }
 
-/**
- * ubifs_reported_space - calculate reported free space.
- * @c: the UBIFS file-system description object
- * @free: amount of free space
- *
- * This function calculates amount of free space which will be reported to
- * user-space. User-space application tend to expect that if the file-system
- * (e.g., via the 'statfs()' call) reports that it has N bytes available, they
- * are able to write a file of size N. UBIFS attaches node headers to each data
- * node and it has to write indexind nodes as well. This introduces additional
- * overhead, and UBIFS it has to report sligtly less free space to meet the
- * above expectetion.
- *
- * This function assumes free space is made up of uncompressed data nodes and
- * full index nodes (one per data node, doubled because we always allow enough
- * space to write the index twice).
- *
- * Note, the calculation is pessimistic, which means that most of the time
- * UBIFS reports less space than it actually has.
- */
-static inline long long ubifs_reported_space(const struct ubifs_info *c,
-                                            uint64_t free)
-{
-       int divisor, factor;
-
-       divisor = UBIFS_MAX_DATA_NODE_SZ + (c->max_idx_node_sz * 3);
-       factor = UBIFS_MAX_DATA_NODE_SZ - UBIFS_DATA_NODE_SZ;
-       do_div(free, divisor);
-
-       return free * factor;
-}
-
 /**
  * ubifs_current_time - round current time to time granularity.
  * @inode: inode
@@ -325,4 +293,21 @@ static inline struct timespec ubifs_current_time(struct inode *inode)
                current_fs_time(inode->i_sb) : CURRENT_TIME_SEC;
 }
 
+/**
+ * ubifs_tnc_lookup - look up a file-system node.
+ * @c: UBIFS file-system description object
+ * @key: node key to lookup
+ * @node: the node is returned here
+ *
+ * This function look up and reads node with key @key. The caller has to make
+ * sure the @node buffer is large enough to fit the node. Returns zero in case
+ * of success, %-ENOENT if the node was not found, and a negative error code in
+ * case of failure.
+ */
+static inline int ubifs_tnc_lookup(struct ubifs_info *c,
+                                  const union ubifs_key *key, void *node)
+{
+       return ubifs_tnc_locate(c, key, node, NULL, NULL);
+}
+
 #endif /* __UBIFS_MISC_H__ */
index f71e6b8822c4fac6dbaab1913098e7a61c81dcfa..3f4902060c7a10aba197a73c07491b7aca4cc84e 100644 (file)
@@ -370,8 +370,9 @@ static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct ubifs_info *c = dentry->d_sb->s_fs_info;
        unsigned long long free;
+       __le32 *uuid = (__le32 *)c->uuid;
 
-       free = ubifs_budg_get_free_space(c);
+       free = ubifs_get_free_space(c);
        dbg_gen("free space %lld bytes (%lld blocks)",
                free, free >> UBIFS_BLOCK_SHIFT);
 
@@ -386,7 +387,8 @@ static int ubifs_statfs(struct dentry *dentry, struct kstatfs *buf)
        buf->f_files = 0;
        buf->f_ffree = 0;
        buf->f_namelen = UBIFS_MAX_NLEN;
-
+       buf->f_fsid.val[0] = le32_to_cpu(uuid[0]) ^ le32_to_cpu(uuid[2]);
+       buf->f_fsid.val[1] = le32_to_cpu(uuid[1]) ^ le32_to_cpu(uuid[3]);
        return 0;
 }
 
@@ -530,6 +532,12 @@ static int init_constants_early(struct ubifs_info *c)
        c->dead_wm = ALIGN(MIN_WRITE_SZ, c->min_io_size);
        c->dark_wm = ALIGN(UBIFS_MAX_NODE_SZ, c->min_io_size);
 
+       /*
+        * Calculate how many bytes would be wasted at the end of LEB if it was
+        * fully filled with data nodes of maximum size. This is used in
+        * calculations when reporting free space.
+        */
+       c->leb_overhead = c->leb_size % UBIFS_MAX_DATA_NODE_SZ;
        return 0;
 }
 
@@ -647,13 +655,11 @@ static int init_constants_late(struct ubifs_info *c)
         * internally because it does not make much sense for UBIFS, but it is
         * necessary to report something for the 'statfs()' call.
         *
-        * Subtract the LEB reserved for GC and the LEB which is reserved for
-        * deletions.
-        *
-        * Review 'ubifs_calc_available()' if changing this calculation.
+        * Subtract the LEB reserved for GC, the LEB which is reserved for
+        * deletions, and assume only one journal head is available.
         */
-       tmp64 = c->main_lebs - 2;
-       tmp64 *= (uint64_t)c->leb_size - c->dark_wm;
+       tmp64 = c->main_lebs - 2 - c->jhead_cnt + 1;
+       tmp64 *= (uint64_t)c->leb_size - c->leb_overhead;
        tmp64 = ubifs_reported_space(c, tmp64);
        c->block_cnt = tmp64 >> UBIFS_BLOCK_SHIFT;
 
@@ -1018,14 +1024,13 @@ static int mount_ubifs(struct ubifs_info *c)
                goto out_dereg;
        }
 
+       sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num, c->vi.vol_id);
        if (!mounted_read_only) {
                err = alloc_wbufs(c);
                if (err)
                        goto out_cbuf;
 
                /* Create background thread */
-               sprintf(c->bgt_name, BGT_NAME_PATTERN, c->vi.ubi_num,
-                       c->vi.vol_id);
                c->bgt = kthread_create(ubifs_bg_thread, c, c->bgt_name);
                if (!c->bgt)
                        c->bgt = ERR_PTR(-EINVAL);
index e909f4a96443a65de717771b3004344f02263332..7634c5970887960a9555e82757bf11ffe704a5f3 100644 (file)
@@ -506,7 +506,7 @@ static int fallible_read_node(struct ubifs_info *c, const union ubifs_key *key,
                if (keys_cmp(c, key, &node_key) != 0)
                        ret = 0;
        }
-       if (ret == 0)
+       if (ret == 0 && c->replaying)
                dbg_mnt("dangling branch LEB %d:%d len %d, key %s",
                        zbr->lnum, zbr->offs, zbr->len, DBGKEY(key));
        return ret;
@@ -1382,50 +1382,39 @@ static int lookup_level0_dirty(struct ubifs_info *c, const union ubifs_key *key,
 }
 
 /**
- * ubifs_tnc_lookup - look up a file-system node.
+ * maybe_leb_gced - determine if a LEB may have been garbage collected.
  * @c: UBIFS file-system description object
- * @key: node key to lookup
- * @node: the node is returned here
+ * @lnum: LEB number
+ * @gc_seq1: garbage collection sequence number
  *
- * This function look up and reads node with key @key. The caller has to make
- * sure the @node buffer is large enough to fit the node. Returns zero in case
- * of success, %-ENOENT if the node was not found, and a negative error code in
- * case of failure.
+ * This function determines if @lnum may have been garbage collected since
+ * sequence number @gc_seq1. If it may have been then %1 is returned, otherwise
+ * %0 is returned.
  */
-int ubifs_tnc_lookup(struct ubifs_info *c, const union ubifs_key *key,
-                    void *node)
+static int maybe_leb_gced(struct ubifs_info *c, int lnum, int gc_seq1)
 {
-       int found, n, err;
-       struct ubifs_znode *znode;
-       struct ubifs_zbranch zbr, *zt;
+       int gc_seq2, gced_lnum;
 
-       mutex_lock(&c->tnc_mutex);
-       found = ubifs_lookup_level0(c, key, &znode, &n);
-       if (!found) {
-               err = -ENOENT;
-               goto out;
-       } else if (found < 0) {
-               err = found;
-               goto out;
-       }
-       zt = &znode->zbranch[n];
-       if (is_hash_key(c, key)) {
-               /*
-                * In this case the leaf node cache gets used, so we pass the
-                * address of the zbranch and keep the mutex locked
-                */
-               err = tnc_read_node_nm(c, zt, node);
-               goto out;
-       }
-       zbr = znode->zbranch[n];
-       mutex_unlock(&c->tnc_mutex);
-
-       err = ubifs_tnc_read_node(c, &zbr, node);
-       return err;
-
-out:
-       mutex_unlock(&c->tnc_mutex);
-       return err;
+       gced_lnum = c->gced_lnum;
+       smp_rmb();
+       gc_seq2 = c->gc_seq;
+       /* Same seq means no GC */
+       if (gc_seq1 == gc_seq2)
+               return 0;
+       /* Different by more than 1 means we don't know */
+       if (gc_seq1 + 1 != gc_seq2)
+               return 1;
+       /*
+        * We have seen the sequence number has increased by 1. Now we need to
+        * be sure we read the right LEB number, so read it again.
+        */
+       smp_rmb();
+       if (gced_lnum != c->gced_lnum)
+               return 1;
+       /* Finally we can check lnum */
+       if (gced_lnum == lnum)
+               return 1;
+       return 0;
 }
 
 /**
@@ -1436,16 +1425,19 @@ out:
  * @lnum: LEB number is returned here
  * @offs: offset is returned here
  *
- * This function is the same as 'ubifs_tnc_lookup()' but it returns the node
- * location also. See 'ubifs_tnc_lookup()'.
+ * This function look up and reads node with key @key. The caller has to make
+ * sure the @node buffer is large enough to fit the node. Returns zero in case
+ * of success, %-ENOENT if the node was not found, and a negative error code in
+ * case of failure. The node location can be returned in @lnum and @offs.
  */
 int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key,
                     void *node, int *lnum, int *offs)
 {
-       int found, n, err;
+       int found, n, err, safely = 0, gc_seq1;
        struct ubifs_znode *znode;
        struct ubifs_zbranch zbr, *zt;
 
+again:
        mutex_lock(&c->tnc_mutex);
        found = ubifs_lookup_level0(c, key, &znode, &n);
        if (!found) {
@@ -1456,24 +1448,43 @@ int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key,
                goto out;
        }
        zt = &znode->zbranch[n];
+       if (lnum) {
+               *lnum = zt->lnum;
+               *offs = zt->offs;
+       }
        if (is_hash_key(c, key)) {
                /*
                 * In this case the leaf node cache gets used, so we pass the
                 * address of the zbranch and keep the mutex locked
                 */
-               *lnum = zt->lnum;
-               *offs = zt->offs;
                err = tnc_read_node_nm(c, zt, node);
                goto out;
        }
+       if (safely) {
+               err = ubifs_tnc_read_node(c, zt, node);
+               goto out;
+       }
+       /* Drop the TNC mutex prematurely and race with garbage collection */
        zbr = znode->zbranch[n];
+       gc_seq1 = c->gc_seq;
        mutex_unlock(&c->tnc_mutex);
 
-       *lnum = zbr.lnum;
-       *offs = zbr.offs;
+       if (ubifs_get_wbuf(c, zbr.lnum)) {
+               /* We do not GC journal heads */
+               err = ubifs_tnc_read_node(c, &zbr, node);
+               return err;
+       }
 
-       err = ubifs_tnc_read_node(c, &zbr, node);
-       return err;
+       err = fallible_read_node(c, key, &zbr, node);
+       if (err <= 0 || maybe_leb_gced(c, zbr.lnum, gc_seq1)) {
+               /*
+                * The node may have been GC'ed out from under us so try again
+                * while keeping the TNC mutex locked.
+                */
+               safely = 1;
+               goto again;
+       }
+       return 0;
 
 out:
        mutex_unlock(&c->tnc_mutex);
@@ -1498,7 +1509,6 @@ static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
 {
        int found, n, err;
        struct ubifs_znode *znode;
-       struct ubifs_zbranch zbr;
 
        dbg_tnc("name '%.*s' key %s", nm->len, nm->name, DBGKEY(key));
        mutex_lock(&c->tnc_mutex);
@@ -1522,11 +1532,7 @@ static int do_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
                goto out_unlock;
        }
 
-       zbr = znode->zbranch[n];
-       mutex_unlock(&c->tnc_mutex);
-
-       err = tnc_read_node_nm(c, &zbr, node);
-       return err;
+       err = tnc_read_node_nm(c, &znode->zbranch[n], node);
 
 out_unlock:
        mutex_unlock(&c->tnc_mutex);
index bd2121f3426eb5cacee42602dca1dcacb0150acd..a9ecbd9af20dbeb9a0ddefccd21f8b7393ba1d0a 100644 (file)
@@ -87,7 +87,7 @@
 #define UBIFS_SK_LEN 8
 
 /* Minimum index tree fanout */
-#define UBIFS_MIN_FANOUT 2
+#define UBIFS_MIN_FANOUT 3
 
 /* Maximum number of levels in UBIFS indexing B-tree */
 #define UBIFS_MAX_LEVELS 512
index d7f706f7a3024ab18200c382e790202273adc1e4..17c620b93eec324ced7165b4b2de16482e1b8fda 100644 (file)
@@ -995,6 +995,9 @@ struct ubifs_mount_opts {
  * @max_idx_node_sz: maximum indexing node aligned on 8-bytes boundary
  * @max_inode_sz: maximum possible inode size in bytes
  * @max_znode_sz: size of znode in bytes
+ *
+ * @leb_overhead: how many bytes are wasted in an LEB when it is filled with
+ *                data nodes of maximum size - used in free space reporting
  * @dead_wm: LEB dead space watermark
  * @dark_wm: LEB dark space watermark
  * @block_cnt: count of 4KiB blocks on the FS
@@ -1028,6 +1031,8 @@ struct ubifs_mount_opts {
  * @sbuf: a buffer of LEB size used by GC and replay for scanning
  * @idx_gc: list of index LEBs that have been garbage collected
  * @idx_gc_cnt: number of elements on the idx_gc list
+ * @gc_seq: incremented for every non-index LEB garbage collected
+ * @gced_lnum: last non-index LEB that was garbage collected
  *
  * @infos_list: links all 'ubifs_info' objects
  * @umount_mutex: serializes shrinker and un-mount
@@ -1224,6 +1229,8 @@ struct ubifs_info {
        int max_idx_node_sz;
        long long max_inode_sz;
        int max_znode_sz;
+
+       int leb_overhead;
        int dead_wm;
        int dark_wm;
        int block_cnt;
@@ -1257,6 +1264,8 @@ struct ubifs_info {
        void *sbuf;
        struct list_head idx_gc;
        int idx_gc_cnt;
+       volatile int gc_seq;
+       volatile int gced_lnum;
 
        struct list_head infos_list;
        struct mutex umount_mutex;
@@ -1434,9 +1443,10 @@ void ubifs_release_ino_dirty(struct ubifs_info *c, struct inode *inode,
                                struct ubifs_budget_req *req);
 void ubifs_cancel_ino_op(struct ubifs_info *c, struct inode *inode,
                         struct ubifs_budget_req *req);
-long long ubifs_budg_get_free_space(struct ubifs_info *c);
+long long ubifs_get_free_space(struct ubifs_info *c);
 int ubifs_calc_min_idx_lebs(struct ubifs_info *c);
 void ubifs_convert_page_budget(struct ubifs_info *c);
+long long ubifs_reported_space(const struct ubifs_info *c, uint64_t free);
 long long ubifs_calc_available(const struct ubifs_info *c, int min_idx_lebs);
 
 /* find.c */
@@ -1451,8 +1461,6 @@ int ubifs_save_dirty_idx_lnums(struct ubifs_info *c);
 /* tnc.c */
 int ubifs_lookup_level0(struct ubifs_info *c, const union ubifs_key *key,
                        struct ubifs_znode **zn, int *n);
-int ubifs_tnc_lookup(struct ubifs_info *c, const union ubifs_key *key,
-                    void *node);
 int ubifs_tnc_lookup_nm(struct ubifs_info *c, const union ubifs_key *key,
                        void *node, const struct qstr *nm);
 int ubifs_tnc_locate(struct ubifs_info *c, const union ubifs_key *key,
index 0ed6e146a0d9968939a45b09fec96a2bf42e9e5e..eb91f3b703201ec1669470ad5835a59a26de4b8f 100644 (file)
@@ -211,6 +211,7 @@ const struct file_operations udf_file_operations = {
        .release                = udf_release_file,
        .fsync                  = udf_fsync_file,
        .splice_read            = generic_file_splice_read,
+       .llseek                 = generic_file_llseek,
 };
 
 const struct inode_operations udf_file_inode_operations = {
index eb9cfa23dc3d37f690edd63c9bf893844493979a..a4f2b3ce45b053ca76168a01d93b38974d34a949 100644 (file)
@@ -76,11 +76,24 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
        *err = -ENOSPC;
 
        iinfo = UDF_I(inode);
-       iinfo->i_unique = 0;
-       iinfo->i_lenExtents = 0;
-       iinfo->i_next_alloc_block = 0;
-       iinfo->i_next_alloc_goal = 0;
-       iinfo->i_strat4096 = 0;
+       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) {
+               iinfo->i_efe = 1;
+               if (UDF_VERS_USE_EXTENDED_FE > sbi->s_udfrev)
+                       sbi->s_udfrev = UDF_VERS_USE_EXTENDED_FE;
+               iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
+                                           sizeof(struct extendedFileEntry),
+                                           GFP_KERNEL);
+       } else {
+               iinfo->i_efe = 0;
+               iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
+                                           sizeof(struct fileEntry),
+                                           GFP_KERNEL);
+       }
+       if (!iinfo->i_ext.i_data) {
+               iput(inode);
+               *err = -ENOMEM;
+               return NULL;
+       }
 
        block = udf_new_block(dir->i_sb, NULL,
                              dinfo->i_location.partitionReferenceNum,
@@ -111,6 +124,7 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
                lvhd->uniqueID = cpu_to_le64(uniqueID);
                mark_buffer_dirty(sbi->s_lvid_bh);
        }
+       mutex_unlock(&sbi->s_alloc_mutex);
        inode->i_mode = mode;
        inode->i_uid = current->fsuid;
        if (dir->i_mode & S_ISGID) {
@@ -129,25 +143,6 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
        iinfo->i_lenEAttr = 0;
        iinfo->i_lenAlloc = 0;
        iinfo->i_use = 0;
-       if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) {
-               iinfo->i_efe = 1;
-               if (UDF_VERS_USE_EXTENDED_FE > sbi->s_udfrev)
-                       sbi->s_udfrev = UDF_VERS_USE_EXTENDED_FE;
-               iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
-                                           sizeof(struct extendedFileEntry),
-                                           GFP_KERNEL);
-       } else {
-               iinfo->i_efe = 0;
-               iinfo->i_ext.i_data = kzalloc(inode->i_sb->s_blocksize -
-                                           sizeof(struct fileEntry),
-                                           GFP_KERNEL);
-       }
-       if (!iinfo->i_ext.i_data) {
-               iput(inode);
-               *err = -ENOMEM;
-               mutex_unlock(&sbi->s_alloc_mutex);
-               return NULL;
-       }
        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB))
                iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB;
        else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD))
@@ -158,7 +153,6 @@ struct inode *udf_new_inode(struct inode *dir, int mode, int *err)
                iinfo->i_crtime = current_fs_time(inode->i_sb);
        insert_inode_hash(inode);
        mark_inode_dirty(inode);
-       mutex_unlock(&sbi->s_alloc_mutex);
 
        if (DQUOT_ALLOC_INODE(inode)) {
                DQUOT_DROP(inode);
index f42f80a3b1faca317f3e08b021c532f19e0512cc..a44d68eb50b5302b8482000e523661b14c0854d8 100644 (file)
@@ -1338,6 +1338,10 @@ __xfs_get_blocks(
        offset = (xfs_off_t)iblock << inode->i_blkbits;
        ASSERT(bh_result->b_size >= (1 << inode->i_blkbits));
        size = bh_result->b_size;
+
+       if (!create && direct && offset >= i_size_read(inode))
+               return 0;
+
        error = xfs_iomap(XFS_I(inode), offset, size,
                             create ? flags : BMAPI_READ, &iomap, &niomap);
        if (error)
index 73c65f19e549f34dbf569cea7937b5971c44685e..18d3c848783511da1848ed56800a47b533be5b3d 100644 (file)
@@ -1302,9 +1302,29 @@ xfs_fs_remount(
                        mp->m_flags &= ~XFS_MOUNT_BARRIER;
                        break;
                default:
+                       /*
+                        * Logically we would return an error here to prevent
+                        * users from believing they might have changed
+                        * mount options using remount which can't be changed.
+                        *
+                        * But unfortunately mount(8) adds all options from
+                        * mtab and fstab to the mount arguments in some cases
+                        * so we can't blindly reject options, but have to
+                        * check for each specified option if it actually
+                        * differs from the currently set option and only
+                        * reject it if that's the case.
+                        *
+                        * Until that is implemented we return success for
+                        * every remount request, and silently ignore all
+                        * options that we can't actually change.
+                        */
+#if 0
                        printk(KERN_INFO
        "XFS: mount option \"%s\" not supported for remount\n", p);
                        return -EINVAL;
+#else
+                       return 0;
+#endif
                }
        }
 
index 608c30c3f76b872b8e553d325364407eff489593..002fc2617c8ee9426bff6203eb5bc6039094bf0a 100644 (file)
@@ -732,6 +732,7 @@ xfs_buf_item_init(
        bip->bli_item.li_ops = &xfs_buf_item_ops;
        bip->bli_item.li_mountp = mp;
        bip->bli_buf = bp;
+       xfs_buf_hold(bp);
        bip->bli_format.blf_type = XFS_LI_BUF;
        bip->bli_format.blf_blkno = (__int64_t)XFS_BUF_ADDR(bp);
        bip->bli_format.blf_len = (ushort)BTOBB(XFS_BUF_COUNT(bp));
@@ -867,6 +868,21 @@ xfs_buf_item_dirty(
        return (bip->bli_flags & XFS_BLI_DIRTY);
 }
 
+STATIC void
+xfs_buf_item_free(
+       xfs_buf_log_item_t      *bip)
+{
+#ifdef XFS_TRANS_DEBUG
+       kmem_free(bip->bli_orig);
+       kmem_free(bip->bli_logged);
+#endif /* XFS_TRANS_DEBUG */
+
+#ifdef XFS_BLI_TRACE
+       ktrace_free(bip->bli_trace);
+#endif
+       kmem_zone_free(xfs_buf_item_zone, bip);
+}
+
 /*
  * This is called when the buf log item is no longer needed.  It should
  * free the buf log item associated with the given buffer and clear
@@ -887,18 +903,8 @@ xfs_buf_item_relse(
            (XFS_BUF_IODONE_FUNC(bp) != NULL)) {
                XFS_BUF_CLR_IODONE_FUNC(bp);
        }
-
-#ifdef XFS_TRANS_DEBUG
-       kmem_free(bip->bli_orig);
-       bip->bli_orig = NULL;
-       kmem_free(bip->bli_logged);
-       bip->bli_logged = NULL;
-#endif /* XFS_TRANS_DEBUG */
-
-#ifdef XFS_BLI_TRACE
-       ktrace_free(bip->bli_trace);
-#endif
-       kmem_zone_free(xfs_buf_item_zone, bip);
+       xfs_buf_rele(bp);
+       xfs_buf_item_free(bip);
 }
 
 
@@ -1120,6 +1126,7 @@ xfs_buf_iodone(
 
        ASSERT(bip->bli_buf == bp);
 
+       xfs_buf_rele(bp);
        mp = bip->bli_item.li_mountp;
 
        /*
@@ -1136,18 +1143,7 @@ xfs_buf_iodone(
         * xfs_trans_delete_ail() drops the AIL lock.
         */
        xfs_trans_delete_ail(mp, (xfs_log_item_t *)bip);
-
-#ifdef XFS_TRANS_DEBUG
-       kmem_free(bip->bli_orig);
-       bip->bli_orig = NULL;
-       kmem_free(bip->bli_logged);
-       bip->bli_logged = NULL;
-#endif /* XFS_TRANS_DEBUG */
-
-#ifdef XFS_BLI_TRACE
-       ktrace_free(bip->bli_trace);
-#endif
-       kmem_zone_free(xfs_buf_item_zone, bip);
+       xfs_buf_item_free(bip);
 }
 
 #if defined(XFS_BLI_TRACE)
index 760f4c5b5160c4e648e17d491d8912c691726214..75b0cd4da0ea30140bbdd3068c02ba94c751bd13 100644 (file)
@@ -149,7 +149,14 @@ xfs_swap_extents(
 
        sbp = &sxp->sx_stat;
 
-       xfs_lock_two_inodes(ip, tip, lock_flags);
+       /*
+        * we have to do two separate lock calls here to keep lockdep
+        * happy. If we try to get all the locks in one call, lock will
+        * report false positives when we drop the ILOCK and regain them
+        * below.
+        */
+       xfs_lock_two_inodes(ip, tip, XFS_IOLOCK_EXCL);
+       xfs_lock_two_inodes(ip, tip, XFS_ILOCK_EXCL);
        locked = 1;
 
        /* Verify that both files have the same format */
index 00e80df9dd9d727191f15fefc79cd92055d4e9d6..dbd9cef852ece3d6d8b3b5b930626000c88bed06 100644 (file)
@@ -4118,7 +4118,7 @@ xfs_iext_indirect_to_direct(
        ASSERT(nextents <= XFS_LINEAR_EXTS);
        size = nextents * sizeof(xfs_bmbt_rec_t);
 
-       xfs_iext_irec_compact_full(ifp);
+       xfs_iext_irec_compact_pages(ifp);
        ASSERT(ifp->if_real_bytes == XFS_IEXT_BUFSZ);
 
        ep = ifp->if_u1.if_ext_irec->er_extbuf;
@@ -4449,8 +4449,7 @@ xfs_iext_irec_remove(
  * compaction policy is as follows:
  *
  *    Full Compaction: Extents fit into a single page (or inline buffer)
- *    Full Compaction: Extents occupy less than 10% of allocated space
- * Partial Compaction: Extents occupy > 10% and < 50% of allocated space
+ * Partial Compaction: Extents occupy less than 50% of allocated space
  *      No Compaction: Extents occupy at least 50% of allocated space
  */
 void
@@ -4471,8 +4470,6 @@ xfs_iext_irec_compact(
                xfs_iext_direct_to_inline(ifp, nextents);
        } else if (nextents <= XFS_LINEAR_EXTS) {
                xfs_iext_indirect_to_direct(ifp);
-       } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 3) {
-               xfs_iext_irec_compact_full(ifp);
        } else if (nextents < (nlists * XFS_LINEAR_EXTS) >> 1) {
                xfs_iext_irec_compact_pages(ifp);
        }
@@ -4496,7 +4493,7 @@ xfs_iext_irec_compact_pages(
                erp_next = erp + 1;
                if (erp_next->er_extcount <=
                    (XFS_LINEAR_EXTS - erp->er_extcount)) {
-                       memmove(&erp->er_extbuf[erp->er_extcount],
+                       memcpy(&erp->er_extbuf[erp->er_extcount],
                                erp_next->er_extbuf, erp_next->er_extcount *
                                sizeof(xfs_bmbt_rec_t));
                        erp->er_extcount += erp_next->er_extcount;
@@ -4515,91 +4512,6 @@ xfs_iext_irec_compact_pages(
        }
 }
 
-/*
- * Fully compact the extent records managed by the indirection array.
- */
-void
-xfs_iext_irec_compact_full(
-       xfs_ifork_t     *ifp)                   /* inode fork pointer */
-{
-       xfs_bmbt_rec_host_t *ep, *ep_next;      /* extent record pointers */
-       xfs_ext_irec_t  *erp, *erp_next;        /* extent irec pointers */
-       int             erp_idx = 0;            /* extent irec index */
-       int             ext_avail;              /* empty entries in ex list */
-       int             ext_diff;               /* number of exts to add */
-       int             nlists;                 /* number of irec's (ex lists) */
-
-       ASSERT(ifp->if_flags & XFS_IFEXTIREC);
-
-       nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-       erp = ifp->if_u1.if_ext_irec;
-       ep = &erp->er_extbuf[erp->er_extcount];
-       erp_next = erp + 1;
-       ep_next = erp_next->er_extbuf;
-
-       while (erp_idx < nlists - 1) {
-               /*
-                * Check how many extent records are available in this irec.
-                * If there is none skip the whole exercise.
-                */
-               ext_avail = XFS_LINEAR_EXTS - erp->er_extcount;
-               if (ext_avail) {
-
-                       /*
-                        * Copy over as many as possible extent records into
-                        * the previous page.
-                        */
-                       ext_diff = MIN(ext_avail, erp_next->er_extcount);
-                       memcpy(ep, ep_next, ext_diff * sizeof(xfs_bmbt_rec_t));
-                       erp->er_extcount += ext_diff;
-                       erp_next->er_extcount -= ext_diff;
-
-                       /*
-                        * If the next irec is empty now we can simply
-                        * remove it.
-                        */
-                       if (erp_next->er_extcount == 0) {
-                               /*
-                                * Free page before removing extent record
-                                * so er_extoffs don't get modified in
-                                * xfs_iext_irec_remove.
-                                */
-                               kmem_free(erp_next->er_extbuf);
-                               erp_next->er_extbuf = NULL;
-                               xfs_iext_irec_remove(ifp, erp_idx + 1);
-                               erp = &ifp->if_u1.if_ext_irec[erp_idx];
-                               nlists = ifp->if_real_bytes / XFS_IEXT_BUFSZ;
-
-                       /*
-                        * If the next irec is not empty move up the content
-                        * that has not been copied to the previous page to
-                        * the beggining of this one.
-                        */
-                       } else {
-                               memmove(erp_next->er_extbuf, &ep_next[ext_diff],
-                                       erp_next->er_extcount *
-                                       sizeof(xfs_bmbt_rec_t));
-                               ep_next = erp_next->er_extbuf;
-                               memset(&ep_next[erp_next->er_extcount], 0,
-                                       (XFS_LINEAR_EXTS -
-                                               erp_next->er_extcount) *
-                                       sizeof(xfs_bmbt_rec_t));
-                       }
-               }
-
-               if (erp->er_extcount == XFS_LINEAR_EXTS) {
-                       erp_idx++;
-                       if (erp_idx < nlists)
-                               erp = &ifp->if_u1.if_ext_irec[erp_idx];
-                       else
-                               break;
-               }
-               ep = &erp->er_extbuf[erp->er_extcount];
-               erp_next = erp + 1;
-               ep_next = erp_next->er_extbuf;
-       }
-}
-
 /*
  * This is called to update the er_extoff field in the indirection
  * array when extents have been added or removed from one of the
index ccba14eb9dbe373699417a2984eb559854bf5dbb..503ea89e8b9a24ac1b3da0901191ad82673f50f5 100644 (file)
@@ -124,16 +124,27 @@ STATIC void       xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
 STATIC int     xlog_iclogs_empty(xlog_t *log);
 
 #if defined(XFS_LOG_TRACE)
+
+#define XLOG_TRACE_LOGGRANT_SIZE       2048
+#define XLOG_TRACE_ICLOG_SIZE          256
+
+void
+xlog_trace_loggrant_alloc(xlog_t *log)
+{
+       log->l_grant_trace = ktrace_alloc(XLOG_TRACE_LOGGRANT_SIZE, KM_NOFS);
+}
+
+void
+xlog_trace_loggrant_dealloc(xlog_t *log)
+{
+       ktrace_free(log->l_grant_trace);
+}
+
 void
 xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
 {
        unsigned long cnts;
 
-       if (!log->l_grant_trace) {
-               log->l_grant_trace = ktrace_alloc(2048, KM_NOSLEEP);
-               if (!log->l_grant_trace)
-                       return;
-       }
        /* ticket counts are 1 byte each */
        cnts = ((unsigned long)tic->t_ocnt) | ((unsigned long)tic->t_cnt) << 8;
 
@@ -156,11 +167,21 @@ xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
                     (void *)((unsigned long)tic->t_unit_res));
 }
 
+void
+xlog_trace_iclog_alloc(xlog_in_core_t *iclog)
+{
+       iclog->ic_trace = ktrace_alloc(XLOG_TRACE_ICLOG_SIZE, KM_NOFS);
+}
+
+void
+xlog_trace_iclog_dealloc(xlog_in_core_t *iclog)
+{
+       ktrace_free(iclog->ic_trace);
+}
+
 void
 xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
 {
-       if (!iclog->ic_trace)
-               iclog->ic_trace = ktrace_alloc(256, KM_NOFS);
        ktrace_enter(iclog->ic_trace,
                     (void *)((unsigned long)state),
                     (void *)((unsigned long)current_pid()),
@@ -170,8 +191,15 @@ xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
                     (void *)NULL, (void *)NULL);
 }
 #else
+
+#define        xlog_trace_loggrant_alloc(log)
+#define        xlog_trace_loggrant_dealloc(log)
 #define        xlog_trace_loggrant(log,tic,string)
+
+#define        xlog_trace_iclog_alloc(iclog)
+#define        xlog_trace_iclog_dealloc(iclog)
 #define        xlog_trace_iclog(iclog,state)
+
 #endif /* XFS_LOG_TRACE */
 
 
@@ -1009,7 +1037,7 @@ xlog_iodone(xfs_buf_t *bp)
         * layer, it means the underlyin device no longer supports
         * barrier I/O. Warn loudly and turn off barriers.
         */
-       if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ORDERED(bp)) {
+       if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ISORDERED(bp)) {
                l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER;
                xfs_fs_cmn_err(CE_WARN, l->l_mp,
                                "xlog_iodone: Barriers are no longer supported"
@@ -1231,6 +1259,7 @@ xlog_alloc_log(xfs_mount_t        *mp,
        spin_lock_init(&log->l_grant_lock);
        sv_init(&log->l_flush_wait, 0, "flush_wait");
 
+       xlog_trace_loggrant_alloc(log);
        /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */
        ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0);
 
@@ -1285,6 +1314,8 @@ xlog_alloc_log(xfs_mount_t        *mp,
                sv_init(&iclog->ic_force_wait, SV_DEFAULT, "iclog-force");
                sv_init(&iclog->ic_write_wait, SV_DEFAULT, "iclog-write");
 
+               xlog_trace_iclog_alloc(iclog);
+
                iclogp = &iclog->ic_next;
        }
        *iclogp = log->l_iclog;                 /* complete ring */
@@ -1565,11 +1596,7 @@ xlog_dealloc_log(xlog_t *log)
                sv_destroy(&iclog->ic_force_wait);
                sv_destroy(&iclog->ic_write_wait);
                xfs_buf_free(iclog->ic_bp);
-#ifdef XFS_LOG_TRACE
-               if (iclog->ic_trace != NULL) {
-                       ktrace_free(iclog->ic_trace);
-               }
-#endif
+               xlog_trace_iclog_dealloc(iclog);
                next_iclog = iclog->ic_next;
                kmem_free(iclog);
                iclog = next_iclog;
@@ -1578,14 +1605,7 @@ xlog_dealloc_log(xlog_t *log)
        spinlock_destroy(&log->l_grant_lock);
 
        xfs_buf_free(log->l_xbuf);
-#ifdef XFS_LOG_TRACE
-       if (log->l_trace != NULL) {
-               ktrace_free(log->l_trace);
-       }
-       if (log->l_grant_trace != NULL) {
-               ktrace_free(log->l_grant_trace);
-       }
-#endif
+       xlog_trace_loggrant_dealloc(log);
        log->l_mp->m_log = NULL;
        kmem_free(log);
 }      /* xlog_dealloc_log */
index c8a5b22ee3e3b02fa1cd13e639bf2fe9b3f525a7..e7d8f84443fab87ceee83561fb6b1f04685400ff 100644 (file)
@@ -448,7 +448,6 @@ typedef struct log {
        int                     l_grant_write_bytes;
 
 #ifdef XFS_LOG_TRACE
-       struct ktrace           *l_trace;
        struct ktrace           *l_grant_trace;
 #endif
 
index aa238c8fbd7ae605e9f316969bb3012ee4c32f3c..8b6812f66a15bf2895aba5fed5f04be0c22625d8 100644 (file)
@@ -1838,6 +1838,12 @@ again:
 #endif
 }
 
+/*
+ * xfs_lock_two_inodes() can only be used to lock one type of lock
+ * at a time - the iolock or the ilock, but not both at once. If
+ * we lock both at once, lockdep will report false positives saying
+ * we have violated locking orders.
+ */
 void
 xfs_lock_two_inodes(
        xfs_inode_t             *ip0,
@@ -1848,6 +1854,8 @@ xfs_lock_two_inodes(
        int                     attempts = 0;
        xfs_log_item_t          *lp;
 
+       if (lock_mode & (XFS_IOLOCK_SHARED|XFS_IOLOCK_EXCL))
+               ASSERT((lock_mode & (XFS_ILOCK_SHARED|XFS_ILOCK_EXCL)) == 0);
        ASSERT(ip0->i_ino != ip1->i_ino);
 
        if (ip0->i_ino > ip1->i_ino) {
@@ -3152,6 +3160,13 @@ error1:  /* Just cancel transaction */
 /*
  * Zero file bytes between startoff and endoff inclusive.
  * The iolock is held exclusive and no blocks are buffered.
+ *
+ * This function is used by xfs_free_file_space() to zero
+ * partial blocks when the range to free is not block aligned.
+ * When unreserving space with boundaries that are not block
+ * aligned we round up the start and round down the end
+ * boundaries and then use this function to zero the parts of
+ * the blocks that got dropped during the rounding.
  */
 STATIC int
 xfs_zero_remaining_bytes(
@@ -3168,6 +3183,17 @@ xfs_zero_remaining_bytes(
        int                     nimap;
        int                     error = 0;
 
+       /*
+        * Avoid doing I/O beyond eof - it's not necessary
+        * since nothing can read beyond eof.  The space will
+        * be zeroed when the file is extended anyway.
+        */
+       if (startoff >= ip->i_size)
+               return 0;
+
+       if (endoff > ip->i_size)
+               endoff = ip->i_size;
+
        bp = xfs_buf_get_noaddr(mp->m_sb.sb_blocksize,
                                XFS_IS_REALTIME_INODE(ip) ?
                                mp->m_rtdev_targp : mp->m_ddev_targp);
index 8feeae1f2369b64cdf1be263880200503c5c3a41..79a7ff925bf8ea24f0d2fa83a02115113d772a34 100644 (file)
@@ -14,4 +14,10 @@ extern char __kprobes_text_start[], __kprobes_text_end[];
 extern char __initdata_begin[], __initdata_end[];
 extern char __start_rodata[], __end_rodata[];
 
+/* function descriptor handling (if any).  Override
+ * in asm/sections.h */
+#ifndef dereference_function_descriptor
+#define dereference_function_descriptor(p) (p)
+#endif
+
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
index 4396e9ffd418960ed8aa15e17bc32e60587efd57..55813d6150c7ecc47ab0aa63e78e53e278e7f40b 100644 (file)
@@ -57,7 +57,7 @@ extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
 #define PMD_ORDER      1
 #define PTE_ORDER      0
 
-#define PTRS_PER_PGD   ((PAGE_SIZE << PGD_ORDER) / sizeof(pgd_t))
+#define PTRS_PER_PGD   (USER_PTRS_PER_PGD * 2)
 #define PTRS_PER_PTE   ((PAGE_SIZE << PTE_ORDER) / sizeof(pte_t))
 
 #define USER_PTRS_PER_PGD      (0x80000000UL/PGDIR_SIZE)
index fdd43ec42ec56fb5e4ca7552458f81dc35066e53..9d13c3507ad612f95fcc77085cc26e3a2d31192f 100644 (file)
@@ -4,4 +4,9 @@
 /* nothing to see, move along */
 #include <asm-generic/sections.h>
 
+#ifdef CONFIG_64BIT
+#undef dereference_function_descriptor
+void *dereference_function_descriptor(void *);
+#endif
+
 #endif
index 635d764dc13e346e26dc6f27b8a45d5701a9c55b..35d1743b57ac733502f48c63676f313b8e7f61f3 100644 (file)
@@ -140,6 +140,8 @@ static inline unsigned int acpi_processor_cstate_check(unsigned int max_cstate)
            boot_cpu_data.x86_model <= 0x05 &&
            boot_cpu_data.x86_mask < 0x0A)
                return 1;
+       else if (boot_cpu_has(X86_FEATURE_AMDC1E))
+               return 1;
        else
                return max_cstate;
 }
index 9489283a4bcfbc6bbb4f9e8fd5c25dbb8ed547f8..cfcfb0a806bac0d6f591c272c3ad3f65c384d0fe 100644 (file)
@@ -81,6 +81,7 @@
 #define X86_FEATURE_LFENCE_RDTSC (3*32+18) /* Lfence synchronizes RDTSC */
 #define X86_FEATURE_11AP       (3*32+19) /* Bad local APIC aka 11AP */
 #define X86_FEATURE_NOPL       (3*32+20) /* The NOPL (0F 1F) instructions */
+#define X86_FEATURE_AMDC1E     (3*32+21) /* AMD C1E detected */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
index d240e5b30a45d198acd26cf251c34930338d4e37..cbb649123612f003542c463ff99e54062653c306 100644 (file)
@@ -10,4 +10,6 @@ void idle_notifier_register(struct notifier_block *n);
 void enter_idle(void);
 void exit_idle(void);
 
+void c1e_remove_cpu(int cpu);
+
 #endif
index 484c47554f3bc6e76db3eafdb5443c2cda0ba55b..94d63db1036590d95e4666a2059877d6a54bc8d9 100644 (file)
@@ -39,12 +39,13 @@ enum regnames {
        GDB_FS,                 /* 14 */
        GDB_GS,                 /* 15 */
 };
+#define NUMREGBYTES            ((GDB_GS+1)*4)
 #else /* ! CONFIG_X86_32 */
-enum regnames {
+enum regnames64 {
        GDB_AX,                 /* 0 */
-       GDB_DX,                 /* 1 */
+       GDB_BX,                 /* 1 */
        GDB_CX,                 /* 2 */
-       GDB_BX,                 /* 3 */
+       GDB_DX,                 /* 3 */
        GDB_SI,                 /* 4 */
        GDB_DI,                 /* 5 */
        GDB_BP,                 /* 6 */
@@ -58,18 +59,15 @@ enum regnames {
        GDB_R14,                /* 14 */
        GDB_R15,                /* 15 */
        GDB_PC,                 /* 16 */
-       GDB_PS,                 /* 17 */
 };
-#endif /* CONFIG_X86_32 */
 
-/*
- * Number of bytes of registers:
- */
-#ifdef CONFIG_X86_32
-# define NUMREGBYTES           64
-#else
-# define NUMREGBYTES           ((GDB_PS+1)*8)
-#endif
+enum regnames32 {
+       GDB_PS = 34,
+       GDB_CS,
+       GDB_SS,
+};
+#define NUMREGBYTES            ((GDB_SS+1)*4)
+#endif /* CONFIG_X86_32 */
 
 static inline void arch_kgdb_breakpoint(void)
 {
index b68ec09399be562110b92b0903a26ca058875e0e..f431e40725d666da967faa28420acb92056bd694 100644 (file)
@@ -126,6 +126,7 @@ header-y += pci_regs.h
 header-y += pfkeyv2.h
 header-y += pg.h
 header-y += phantom.h
+header-y += phonet.h
 header-y += pkt_cls.h
 header-y += pkt_sched.h
 header-y += posix_types.h
@@ -232,6 +233,7 @@ unifdef-y += if_fddi.h
 unifdef-y += if_frad.h
 unifdef-y += if_ltalk.h
 unifdef-y += if_link.h
+unifdef-y += if_phonet.h
 unifdef-y += if_pppol2tp.h
 unifdef-y += if_pppox.h
 unifdef-y += if_tr.h
index 1ce19c1ef0e93cbcfcaded43c8a95489ad9d271a..8a12d718c16931892d7842a9e6e3c3e6020b2443 100644 (file)
@@ -745,7 +745,7 @@ static inline int ata_ok(u8 status)
 static inline int lba_28_ok(u64 block, u32 n_block)
 {
        /* check the ending block number */
-       return ((block + n_block - 1) < ((u64)1 << 28)) && (n_block <= 256);
+       return ((block + n_block) < ((u64)1 << 28)) && (n_block <= 256);
 }
 
 static inline int lba_48_ok(u64 block, u32 n_block)
index 44710d7e7bff888c302038fb5c00a64e5d31367b..53ea933cf60bde455e4abc0687e06da638641b8a 100644 (file)
@@ -843,8 +843,6 @@ extern int blkdev_issue_flush(struct block_device *, sector_t *);
 */
 extern int blk_verify_command(struct blk_cmd_filter *filter,
                              unsigned char *cmd, int has_write_perm);
-extern int blk_register_filter(struct gendisk *disk);
-extern void blk_unregister_filter(struct gendisk *disk);
 extern void blk_set_cmd_filter_defaults(struct blk_cmd_filter *filter);
 
 #define MAX_PHYS_SEGMENTS 128
similarity index 87%
rename from arch/arm/include/asm/cnt32_to_63.h
rename to include/linux/cnt32_to_63.h
index 480c873fa746ec8a5da3d371846b643e66ecba21..8c0f9505b48cbed9cab8b268ec67519df0f01ddc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  include/asm/cnt32_to_63.h -- extend a 32-bit counter to 63 bits
+ *  Extend a 32-bit counter to 63 bits
  *
  *  Author:    Nicolas Pitre
  *  Created:   December 3, 2006
  * as published by the Free Software Foundation.
  */
 
-#ifndef __INCLUDE_CNT32_TO_63_H__
-#define __INCLUDE_CNT32_TO_63_H__
+#ifndef __LINUX_CNT32_TO_63_H__
+#define __LINUX_CNT32_TO_63_H__
 
 #include <linux/compiler.h>
-#include <asm/types.h>
+#include <linux/types.h>
 #include <asm/byteorder.h>
 
-/*
- * Prototype: u64 cnt32_to_63(u32 cnt)
+/* this is used only to give gcc a clue about good code generation */
+union cnt32_to_63 {
+       struct {
+#if defined(__LITTLE_ENDIAN)
+               u32 lo, hi;
+#elif defined(__BIG_ENDIAN)
+               u32 hi, lo;
+#endif
+       };
+       u64 val;
+};
+
+
+/**
+ * cnt32_to_63 - Expand a 32-bit counter to a 63-bit counter
+ * @cnt_lo: The low part of the counter
+ *
  * Many hardware clock counters are only 32 bits wide and therefore have
  * a relatively short period making wrap-arounds rather frequent.  This
  * is a problem when implementing sched_clock() for example, where a 64-bit
  * clear-bit instruction. Otherwise caller must remember to clear the top
  * bit explicitly.
  */
-
-/* this is used only to give gcc a clue about good code generation */
-typedef union {
-       struct {
-#if defined(__LITTLE_ENDIAN)
-               u32 lo, hi;
-#elif defined(__BIG_ENDIAN)
-               u32 hi, lo;
-#endif
-       };
-       u64 val;
-} cnt32_to_63_t;
-
 #define cnt32_to_63(cnt_lo) \
 ({ \
-       static volatile u32 __m_cnt_hi = 0; \
-       cnt32_to_63_t __x; \
+       static volatile u32 __m_cnt_hi; \
+       union cnt32_to_63 __x; \
        __x.hi = __m_cnt_hi; \
        __x.lo = (cnt_lo); \
-       if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \
+       if (unlikely((s32)(__x.hi ^ __x.lo) < 0)) \
                __m_cnt_hi = __x.hi = (__x.hi ^ 0x80000000) + (__x.hi >> 31); \
        __x.val; \
 })
index abc1abc63bf093d8b3a377449d59b6e054031ed0..14126bc36641df1d654102136aa8903d2859d994 100644 (file)
@@ -471,6 +471,11 @@ struct ieee80211s_hdr {
        u8 eaddr3[6];
 } __attribute__ ((packed));
 
+/* Mesh flags */
+#define MESH_FLAGS_AE_A4       0x1
+#define MESH_FLAGS_AE_A5_A6    0x2
+#define MESH_FLAGS_PS_DEEP     0x4
+
 /**
  * struct ieee80211_quiet_ie
  *
index 5c9d1fa93fef9f48852ce163f10badd26266f775..65246846c844089e5eef7fce7054789f26ffe817 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/compiler.h>            /* for "__user" et al           */
 
 #define        IFNAMSIZ        16
+#define        IFALIASZ        256
 #include <linux/hdlc/ioctl.h>
 
 /* Standard interface flags (netdevice->flags). */
index 5028e0b6082b55cb20c4537fdbe8daa13361907a..723a1c5fbc6c69b987b9feb183fe8dfc817cf6e3 100644 (file)
 #define ETH_P_ECONET   0x0018          /* Acorn Econet                 */
 #define ETH_P_HDLC     0x0019          /* HDLC frames                  */
 #define ETH_P_ARCNET   0x001A          /* 1A for ArcNet :-)            */
+#define ETH_P_PHONET   0x00F5          /* Nokia Phonet frames          */
 
 /*
  *     This is an Ethernet frame header.
index 84c3492ae5cb510604c50dc4ba09941ac95f7300..f9032c88716a6c3d937adcdff70a3679e89bb887 100644 (file)
@@ -79,6 +79,7 @@ enum
        IFLA_LINKINFO,
 #define IFLA_LINKINFO IFLA_LINKINFO
        IFLA_NET_NS_PID,
+       IFLA_IFALIAS,
        __IFLA_MAX
 };
 
diff --git a/include/linux/if_phonet.h b/include/linux/if_phonet.h
new file mode 100644 (file)
index 0000000..d70034b
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * File: if_phonet.h
+ *
+ * Phonet interface kernel definitions
+ *
+ * Copyright (C) 2008 Nokia Corporation. All rights reserved.
+ */
+#ifndef LINUX_IF_PHONET_H
+#define LINUX_IF_PHONET_H
+
+#define PHONET_MIN_MTU         6       /* pn_length = 0 */
+#define PHONET_MAX_MTU         65541   /* pn_length = 0xffff */
+#define PHONET_DEV_MTU         PHONET_MAX_MTU
+
+#ifdef __KERNEL__
+extern struct header_ops phonet_header_ops;
+#endif
+
+#endif
index 4065313cd7eee7f3a287d3cd0629ffcb726041f1..db458beef19dabe156b52eecab7bd30e11a7e5f9 100644 (file)
@@ -75,6 +75,7 @@ struct in_addr {
 #define IP_IPSEC_POLICY        16
 #define IP_XFRM_POLICY 17
 #define IP_PASSSEC     18
+#define IP_TRANSPARENT 19
 
 /* BSD compatibility */
 #define IP_RECVRETOPTS IP_RETOPTS
index 8d3b7a9afd1780b4624dd28dbd9126db8df738d8..350033e8f4e1936b6ca85bf097de153aef707929 100644 (file)
@@ -159,9 +159,9 @@ extern struct resource * __devm_request_region(struct device *dev,
                                struct resource *parent, resource_size_t start,
                                resource_size_t n, const char *name);
 
-#define devm_release_region(start,n) \
+#define devm_release_region(dev, start, n) \
        __devm_release_region(dev, &ioport_resource, (start), (n))
-#define devm_release_mem_region(start,n) \
+#define devm_release_mem_region(dev, start, n) \
        __devm_release_region(dev, &iomem_resource, (start), (n))
 
 extern void __devm_release_region(struct device *dev, struct resource *parent,
index 8687a7dc0632378c4828b2c58664ec638227919d..4c218ee7587ad47c83c5b7d7375181ee6c2ec9ea 100644 (file)
@@ -157,7 +157,7 @@ typedef struct {
 
 typedef struct {
   int mp_mrru;                        /* unused                             */
-  struct sk_buff * frags;      /* fragments sl list -- use skb->next */
+  struct sk_buff_head frags;   /* fragments sl list */
   long frames;                 /* number of frames in the frame list */
   unsigned int seq;            /* last processed packet seq #: any packets
                                 * with smaller seq # will be dropped
index a9f998a3f48b3d10a35eb0cc08d3e691fe8578e5..d0c37e6822349d56b2462b3df9201bfb9bc6dcb5 100644 (file)
 struct ms_status_register {
        unsigned char reserved;
        unsigned char interrupt;
-#define MEMSTICK_INT_CMDNAK             0x0001
-#define MEMSTICK_INT_IOREQ              0x0008
-#define MEMSTICK_INT_IOBREQ             0x0010
-#define MEMSTICK_INT_BREQ               0x0020
-#define MEMSTICK_INT_ERR                0x0040
-#define MEMSTICK_INT_CED                0x0080
+#define MEMSTICK_INT_CMDNAK 0x01
+#define MEMSTICK_INT_IOREQ  0x08
+#define MEMSTICK_INT_IOBREQ 0x10
+#define MEMSTICK_INT_BREQ   0x20
+#define MEMSTICK_INT_ERR    0x40
+#define MEMSTICK_INT_CED    0x80
 
        unsigned char status0;
-#define MEMSTICK_STATUS0_WP             0x0001
-#define MEMSTICK_STATUS0_SL             0x0002
-#define MEMSTICK_STATUS0_BF             0x0010
-#define MEMSTICK_STATUS0_BE             0x0020
-#define MEMSTICK_STATUS0_FB0            0x0040
-#define MEMSTICK_STATUS0_MB             0x0080
+#define MEMSTICK_STATUS0_WP  0x01
+#define MEMSTICK_STATUS0_SL  0x02
+#define MEMSTICK_STATUS0_BF  0x10
+#define MEMSTICK_STATUS0_BE  0x20
+#define MEMSTICK_STATUS0_FB0 0x40
+#define MEMSTICK_STATUS0_MB  0x80
 
        unsigned char status1;
-#define MEMSTICK_STATUS1_UCFG           0x0001
-#define MEMSTICK_STATUS1_FGER           0x0002
-#define MEMSTICK_STATUS1_UCEX           0x0004
-#define MEMSTICK_STATUS1_EXER           0x0008
-#define MEMSTICK_STATUS1_UCDT           0x0010
-#define MEMSTICK_STATUS1_DTER           0x0020
-#define MEMSTICK_STATUS1_FBI            0x0040
-#define MEMSTICK_STATUS1_MB             0x0080
+#define MEMSTICK_STATUS1_UCFG 0x01
+#define MEMSTICK_STATUS1_FGER 0x02
+#define MEMSTICK_STATUS1_UCEX 0x04
+#define MEMSTICK_STATUS1_EXER 0x08
+#define MEMSTICK_STATUS1_UCDT 0x10
+#define MEMSTICK_STATUS1_DTER 0x20
+#define MEMSTICK_STATUS1_FB1  0x40
+#define MEMSTICK_STATUS1_MB   0x80
 } __attribute__((packed));
 
 struct ms_id_register {
@@ -56,32 +56,32 @@ struct ms_id_register {
 
 struct ms_param_register {
        unsigned char system;
-#define MEMSTICK_SYS_ATEN 0xc0
-#define MEMSTICK_SYS_BAMD 0x80
 #define MEMSTICK_SYS_PAM  0x08
+#define MEMSTICK_SYS_BAMD 0x80
 
        unsigned char block_address_msb;
        unsigned short block_address;
        unsigned char cp;
-#define MEMSTICK_CP_BLOCK               0x0000
-#define MEMSTICK_CP_PAGE                0x0020
-#define MEMSTICK_CP_EXTRA               0x0040
-#define MEMSTICK_CP_OVERWRITE           0x0080
+#define MEMSTICK_CP_BLOCK     0x00
+#define MEMSTICK_CP_PAGE      0x20
+#define MEMSTICK_CP_EXTRA     0x40
+#define MEMSTICK_CP_OVERWRITE 0x80
 
        unsigned char page_address;
 } __attribute__((packed));
 
 struct ms_extra_data_register {
        unsigned char  overwrite_flag;
-#define MEMSTICK_OVERWRITE_UPDATA       0x0010
-#define MEMSTICK_OVERWRITE_PAGE         0x0060
-#define MEMSTICK_OVERWRITE_BLOCK        0x0080
+#define MEMSTICK_OVERWRITE_UDST  0x10
+#define MEMSTICK_OVERWRITE_PGST1 0x20
+#define MEMSTICK_OVERWRITE_PGST0 0x40
+#define MEMSTICK_OVERWRITE_BKST  0x80
 
        unsigned char  management_flag;
-#define MEMSTICK_MANAGEMENT_SYSTEM      0x0004
-#define MEMSTICK_MANAGEMENT_TRANS_TABLE 0x0008
-#define MEMSTICK_MANAGEMENT_COPY        0x0010
-#define MEMSTICK_MANAGEMENT_ACCESS      0x0020
+#define MEMSTICK_MANAGEMENT_SYSFLG 0x04
+#define MEMSTICK_MANAGEMENT_ATFLG  0x08
+#define MEMSTICK_MANAGEMENT_SCMS1  0x10
+#define MEMSTICK_MANAGEMENT_SCMS0  0x20
 
        unsigned short logical_address;
 } __attribute__((packed));
@@ -96,9 +96,9 @@ struct ms_register {
 
 struct mspro_param_register {
        unsigned char  system;
-#define MEMSTICK_SYS_SERIAL 0x80
 #define MEMSTICK_SYS_PAR4   0x00
 #define MEMSTICK_SYS_PAR8   0x40
+#define MEMSTICK_SYS_SERIAL 0x80
 
        unsigned short data_count;
        unsigned int   data_address;
@@ -147,7 +147,7 @@ struct ms_register_addr {
        unsigned char w_length;
 } __attribute__((packed));
 
-enum {
+enum memstick_tpc {
        MS_TPC_READ_MG_STATUS   = 0x01,
        MS_TPC_READ_LONG_DATA   = 0x02,
        MS_TPC_READ_SHORT_DATA  = 0x03,
@@ -167,7 +167,7 @@ enum {
        MS_TPC_SET_CMD          = 0x0e
 };
 
-enum {
+enum memstick_command {
        MS_CMD_BLOCK_END       = 0x33,
        MS_CMD_RESET           = 0x3c,
        MS_CMD_BLOCK_WRITE     = 0x55,
@@ -201,8 +201,6 @@ enum {
 
 /*** Driver structures and functions ***/
 
-#define MEMSTICK_PART_SHIFT 3
-
 enum memstick_param { MEMSTICK_POWER = 1, MEMSTICK_INTERFACE };
 
 #define MEMSTICK_POWER_OFF 0
@@ -215,24 +213,27 @@ enum memstick_param { MEMSTICK_POWER = 1, MEMSTICK_INTERFACE };
 struct memstick_host;
 struct memstick_driver;
 
+struct memstick_device_id {
+       unsigned char match_flags;
 #define MEMSTICK_MATCH_ALL            0x01
 
+       unsigned char type;
 #define MEMSTICK_TYPE_LEGACY          0xff
 #define MEMSTICK_TYPE_DUO             0x00
 #define MEMSTICK_TYPE_PRO             0x01
 
+       unsigned char category;
 #define MEMSTICK_CATEGORY_STORAGE     0xff
 #define MEMSTICK_CATEGORY_STORAGE_DUO 0x00
+#define MEMSTICK_CATEGORY_IO          0x01
+#define MEMSTICK_CATEGORY_IO_PRO      0x10
 
-#define MEMSTICK_CLASS_GENERIC        0xff
-#define MEMSTICK_CLASS_GENERIC_DUO    0x00
-
-
-struct memstick_device_id {
-       unsigned char match_flags;
-       unsigned char type;
-       unsigned char category;
        unsigned char class;
+#define MEMSTICK_CLASS_FLASH          0xff
+#define MEMSTICK_CLASS_DUO            0x00
+#define MEMSTICK_CLASS_ROM            0x01
+#define MEMSTICK_CLASS_RO             0x02
+#define MEMSTICK_CLASS_WP             0x03
 };
 
 struct memstick_request {
@@ -319,9 +320,9 @@ void memstick_suspend_host(struct memstick_host *host);
 void memstick_resume_host(struct memstick_host *host);
 
 void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc,
-                         struct scatterlist *sg);
+                         const struct scatterlist *sg);
 void memstick_init_req(struct memstick_request *mrq, unsigned char tpc,
-                      void *buf, size_t length);
+                      const void *buf, size_t length);
 int memstick_next_req(struct memstick_host *host,
                      struct memstick_request **mrq);
 void memstick_new_req(struct memstick_host *host);
index 655ea0d1ee1474d11a1dbd23c51bf5ef8f679fda..b2f944468313bb296bbdf83d7ff574615a588b1b 100644 (file)
@@ -141,6 +141,10 @@ enum {
        MLX4_STAT_RATE_OFFSET   = 5
 };
 
+enum {
+       MLX4_MTT_FLAG_PRESENT           = 1
+};
+
 static inline u64 mlx4_fw_ver(u64 major, u64 minor, u64 subminor)
 {
        return (major << 32) | (minor << 16) | subminor;
index 443bc7cd8c626ca140ce97e3bec258f101f0ff23..428328a05fa123779a832b4b51731bee45984ea6 100644 (file)
@@ -751,8 +751,9 @@ static inline int zonelist_node_idx(struct zoneref *zoneref)
  *
  * This function returns the next zone at or below a given zone index that is
  * within the allowed nodemask using a cursor as the starting point for the
- * search. The zoneref returned is a cursor that is used as the next starting
- * point for future calls to next_zones_zonelist().
+ * search. The zoneref returned is a cursor that represents the current zone
+ * being examined. It should be advanced by one before calling
+ * next_zones_zonelist again.
  */
 struct zoneref *next_zones_zonelist(struct zoneref *z,
                                        enum zone_type highest_zoneidx,
@@ -768,9 +769,8 @@ struct zoneref *next_zones_zonelist(struct zoneref *z,
  *
  * This function returns the first zone at or below a given zone index that is
  * within the allowed nodemask. The zoneref returned is a cursor that can be
- * used to iterate the zonelist with next_zones_zonelist. The cursor should
- * not be used by the caller as it does not match the value of the zone
- * returned.
+ * used to iterate the zonelist with next_zones_zonelist by advancing it by
+ * one before calling.
  */
 static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist,
                                        enum zone_type highest_zoneidx,
@@ -795,7 +795,7 @@ static inline struct zoneref *first_zones_zonelist(struct zonelist *zonelist,
 #define for_each_zone_zonelist_nodemask(zone, z, zlist, highidx, nodemask) \
        for (z = first_zones_zonelist(zlist, highidx, nodemask, &zone); \
                zone;                                                   \
-               z = next_zones_zonelist(z, highidx, nodemask, &zone))   \
+               z = next_zones_zonelist(++z, highidx, nodemask, &zone)) \
 
 /**
  * for_each_zone_zonelist - helper macro to iterate over valid zones in a zonelist at or below a given zone index
index 12078577aef669d0e8603cb1fe9dcb13df584c63..cbbbe9bfecad0652334963de2cd8363c43e6b28a 100644 (file)
 
 struct mv643xx_eth_shared_platform_data {
        struct mbus_dram_target_info    *dram;
+       struct platform_device  *shared_smi;
        unsigned int            t_clk;
 };
 
+#define MV643XX_ETH_PHY_ADDR_DEFAULT   0
+#define MV643XX_ETH_PHY_ADDR(x)                (0x80 | (x))
+#define MV643XX_ETH_PHY_NONE           0xff
+
 struct mv643xx_eth_platform_data {
        /*
         * Pointer back to our parent instance, and our port number.
@@ -30,8 +35,6 @@ struct mv643xx_eth_platform_data {
        /*
         * Whether a PHY is present, and if yes, at which address.
         */
-       struct platform_device  *shared_smi;
-       int                     force_phy_addr;
        int                     phy_addr;
 
        /*
@@ -49,10 +52,10 @@ struct mv643xx_eth_platform_data {
        int                     duplex;
 
        /*
-        * Which RX/TX queues to use.
+        * How many RX/TX queues to use.
         */
-       int                     rx_queue_mask;
-       int                     tx_queue_mask;
+       int                     rx_queue_count;
+       int                     tx_queue_count;
 
        /*
         * Override default RX/TX queue sizes if nonzero.
index 488c56e649b585592856883043edf4b9dacc8163..9cfd20be8b7fef123018c345ed8324911626b73e 100644 (file)
@@ -471,6 +471,8 @@ struct net_device
        char                    name[IFNAMSIZ];
        /* device name hash chain */
        struct hlist_node       name_hlist;
+       /* snmp alias */
+       char                    *ifalias;
 
        /*
         *      I/O specific fields
@@ -1223,7 +1225,8 @@ extern int                dev_ioctl(struct net *net, unsigned int cmd, void __user *);
 extern int             dev_ethtool(struct net *net, struct ifreq *);
 extern unsigned                dev_get_flags(const struct net_device *);
 extern int             dev_change_flags(struct net_device *, unsigned);
-extern int             dev_change_name(struct net_device *, char *);
+extern int             dev_change_name(struct net_device *, const char *);
+extern int             dev_set_alias(struct net_device *, const char *, size_t);
 extern int             dev_change_net_namespace(struct net_device *,
                                                 struct net *, const char *);
 extern int             dev_set_mtu(struct net_device *, int);
@@ -1667,7 +1670,7 @@ extern void dev_seq_stop(struct seq_file *seq, void *v);
 extern int netdev_class_create_file(struct class_attribute *class_attr);
 extern void netdev_class_remove_file(struct class_attribute *class_attr);
 
-extern char *netdev_drivername(struct net_device *dev, char *buffer, int len);
+extern char *netdev_drivername(const struct net_device *dev, char *buffer, int len);
 
 extern void linkwatch_run_queue(void);
 
index c0e14008a3c2bba4000ff5366bd54c3b24072301..98dc6243a706424ae099853320ef34edab5a8bc8 100644 (file)
@@ -534,7 +534,7 @@ extern void pci_sort_breadthfirst(void);
 #ifdef CONFIG_PCI_LEGACY
 struct pci_dev __deprecated *pci_find_device(unsigned int vendor,
                                             unsigned int device,
-                                            const struct pci_dev *from);
+                                            struct pci_dev *from);
 struct pci_dev __deprecated *pci_find_slot(unsigned int bus,
                                           unsigned int devfn);
 #endif /* CONFIG_PCI_LEGACY */
@@ -550,7 +550,7 @@ struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
                                struct pci_dev *from);
 struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device,
                                unsigned int ss_vendor, unsigned int ss_device,
-                               const struct pci_dev *from);
+                               struct pci_dev *from);
 struct pci_dev *pci_get_slot(struct pci_bus *bus, unsigned int devfn);
 struct pci_dev *pci_get_bus_and_slot(unsigned int bus, unsigned int devfn);
 struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from);
@@ -816,7 +816,7 @@ _PCI_NOP_ALL(write,)
 
 static inline struct pci_dev *pci_find_device(unsigned int vendor,
                                              unsigned int device,
-                                             const struct pci_dev *from)
+                                             struct pci_dev *from)
 {
        return NULL;
 }
@@ -838,7 +838,7 @@ static inline struct pci_dev *pci_get_subsys(unsigned int vendor,
                                             unsigned int device,
                                             unsigned int ss_vendor,
                                             unsigned int ss_device,
-                                            const struct pci_dev *from)
+                                            struct pci_dev *from)
 {
        return NULL;
 }
index 6f4276d461c07f7dc9790fe7fbeee55e11e3eba6..a65b082a888a3f5341d21a0c41decee96693d75c 100644 (file)
 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007
 #define PCI_DEVICE_ID_3DLABS_PERMEDIA2V        0x0009
 
+#define PCI_VENDOR_ID_NETXEN           0x4040
+#define PCI_DEVICE_ID_NX2031_10GXSR    0x0001
+#define PCI_DEVICE_ID_NX2031_10GCX4    0x0002
+#define PCI_DEVICE_ID_NX2031_4GCU      0x0003
+#define PCI_DEVICE_ID_NX2031_IMEZ      0x0004
+#define PCI_DEVICE_ID_NX2031_HMEZ      0x0005
+#define PCI_DEVICE_ID_NX2031_XG_MGMT   0x0024
+#define PCI_DEVICE_ID_NX2031_XG_MGMT2  0x0025
+#define PCI_DEVICE_ID_NX3031           0x0100
+
 #define PCI_VENDOR_ID_AKS              0x416c
 #define PCI_DEVICE_ID_AKS_ALADDINCARD  0x0100
 
index 700725ddcaae3edf050fb6093e516d5abd7c67c3..01b262959f2ef0d41efce74aa06dcd2bf7f0995d 100644 (file)
@@ -226,6 +226,15 @@ struct sadb_x_sec_ctx {
 } __attribute__((packed));
 /* sizeof(struct sadb_sec_ctx) = 8 */
 
+/* Used by MIGRATE to pass addresses IKE will use to perform
+ * negotiation with the peer */
+struct sadb_x_kmaddress {
+       uint16_t        sadb_x_kmaddress_len;
+       uint16_t        sadb_x_kmaddress_exttype;
+       uint32_t        sadb_x_kmaddress_reserved;
+} __attribute__((packed));
+/* sizeof(struct sadb_x_kmaddress) == 8 */
+
 /* Message types */
 #define SADB_RESERVED          0
 #define SADB_GETSPI            1
@@ -346,7 +355,9 @@ struct sadb_x_sec_ctx {
 #define SADB_X_EXT_NAT_T_DPORT         22
 #define SADB_X_EXT_NAT_T_OA            23
 #define SADB_X_EXT_SEC_CTX             24
-#define SADB_EXT_MAX                   24
+/* Used with MIGRATE to pass @ to IKE for negotiation */
+#define SADB_X_EXT_KMADDRESS           25
+#define SADB_EXT_MAX                   25
 
 /* Identity Extension values */
 #define SADB_IDENTTYPE_RESERVED        0
diff --git a/include/linux/phonet.h b/include/linux/phonet.h
new file mode 100644 (file)
index 0000000..c9609f9
--- /dev/null
@@ -0,0 +1,170 @@
+/**
+ * file phonet.h
+ *
+ * Phonet sockets kernel interface
+ *
+ * Copyright (C) 2008 Nokia Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef LINUX_PHONET_H
+#define LINUX_PHONET_H
+
+/* Automatic protocol selection */
+#define PN_PROTO_TRANSPORT     0
+/* Phonet datagram socket */
+#define PN_PROTO_PHONET                1
+/* Phonet pipe */
+#define PN_PROTO_PIPE          2
+#define PHONET_NPROTO          3
+
+/* Socket options for SOL_PNPIPE level */
+#define PNPIPE_ENCAP           1
+#define PNPIPE_IFINDEX         2
+
+#define PNADDR_ANY             0
+#define PNPORT_RESOURCE_ROUTING        0
+
+/* Values for PNPIPE_ENCAP option */
+#define PNPIPE_ENCAP_NONE      0
+#define PNPIPE_ENCAP_IP                1
+
+/* ioctls */
+#define SIOCPNGETOBJECT                (SIOCPROTOPRIVATE + 0)
+
+/* Phonet protocol header */
+struct phonethdr {
+       __u8    pn_rdev;
+       __u8    pn_sdev;
+       __u8    pn_res;
+       __be16  pn_length;
+       __u8    pn_robj;
+       __u8    pn_sobj;
+} __attribute__((packed));
+
+/* Common Phonet payload header */
+struct phonetmsg {
+       __u8    pn_trans_id;    /* transaction ID */
+       __u8    pn_msg_id;      /* message type */
+       union {
+               struct {
+                       __u8    pn_submsg_id;   /* message subtype */
+                       __u8    pn_data[5];
+               } base;
+               struct {
+                       __u16   pn_e_res_id;    /* extended resource ID */
+                       __u8    pn_e_submsg_id; /* message subtype */
+                       __u8    pn_e_data[3];
+               } ext;
+       } pn_msg_u;
+};
+#define PN_COMMON_MESSAGE      0xF0
+#define PN_PREFIX              0xE0 /* resource for extended messages */
+#define pn_submsg_id           pn_msg_u.base.pn_submsg_id
+#define pn_e_submsg_id         pn_msg_u.ext.pn_e_submsg_id
+#define pn_e_res_id            pn_msg_u.ext.pn_e_res_id
+#define pn_data                        pn_msg_u.base.pn_data
+#define pn_e_data              pn_msg_u.ext.pn_e_data
+
+/* data for unreachable errors */
+#define PN_COMM_SERVICE_NOT_IDENTIFIED_RESP    0x01
+#define PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP  0x14
+#define pn_orig_msg_id         pn_data[0]
+#define pn_status              pn_data[1]
+#define pn_e_orig_msg_id       pn_e_data[0]
+#define pn_e_status            pn_e_data[1]
+
+/* Phonet socket address structure */
+struct sockaddr_pn {
+       sa_family_t spn_family;
+       __u8 spn_obj;
+       __u8 spn_dev;
+       __u8 spn_resource;
+       __u8 spn_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - 3];
+} __attribute__ ((packed));
+
+static inline __u16 pn_object(__u8 addr, __u16 port)
+{
+       return (addr << 8) | (port & 0x3ff);
+}
+
+static inline __u8 pn_obj(__u16 handle)
+{
+       return handle & 0xff;
+}
+
+static inline __u8 pn_dev(__u16 handle)
+{
+       return handle >> 8;
+}
+
+static inline __u16 pn_port(__u16 handle)
+{
+       return handle & 0x3ff;
+}
+
+static inline __u8 pn_addr(__u16 handle)
+{
+       return (handle >> 8) & 0xfc;
+}
+
+static inline void pn_sockaddr_set_addr(struct sockaddr_pn *spn, __u8 addr)
+{
+       spn->spn_dev &= 0x03;
+       spn->spn_dev |= addr & 0xfc;
+}
+
+static inline void pn_sockaddr_set_port(struct sockaddr_pn *spn, __u16 port)
+{
+       spn->spn_dev &= 0xfc;
+       spn->spn_dev |= (port >> 8) & 0x03;
+       spn->spn_obj = port & 0xff;
+}
+
+static inline void pn_sockaddr_set_object(struct sockaddr_pn *spn,
+                                               __u16 handle)
+{
+       spn->spn_dev = pn_dev(handle);
+       spn->spn_obj = pn_obj(handle);
+}
+
+static inline void pn_sockaddr_set_resource(struct sockaddr_pn *spn,
+                                               __u8 resource)
+{
+       spn->spn_resource = resource;
+}
+
+static inline __u8 pn_sockaddr_get_addr(const struct sockaddr_pn *spn)
+{
+       return spn->spn_dev & 0xfc;
+}
+
+static inline __u16 pn_sockaddr_get_port(const struct sockaddr_pn *spn)
+{
+       return ((spn->spn_dev & 0x03) << 8) | spn->spn_obj;
+}
+
+static inline __u16 pn_sockaddr_get_object(const struct sockaddr_pn *spn)
+{
+       return pn_object(spn->spn_dev, spn->spn_obj);
+}
+
+static inline __u8 pn_sockaddr_get_resource(const struct sockaddr_pn *spn)
+{
+       return spn->spn_resource;
+}
+
+#endif
index 7224c4099a2820cd8e03b5589fa20e1eeb83b0a6..5f170f5b1a300a838db72950f8d2781c365f0760 100644 (file)
@@ -410,6 +410,8 @@ int phy_start_aneg(struct phy_device *phydev);
 
 int mdiobus_register(struct mii_bus *bus);
 void mdiobus_unregister(struct mii_bus *bus);
+struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
+
 void phy_sanitize_settings(struct phy_device *phydev);
 int phy_stop_interrupts(struct phy_device *phydev);
 int phy_enable_interrupts(struct phy_device *phydev);
index 1ce54b63085dd09b1ee5826694294969fe2a1f78..be764e514e35946eeced5615440769912da9e0fa 100644 (file)
@@ -21,7 +21,14 @@ struct pnp_dev;
 /*
  * Resource Management
  */
+#ifdef CONFIG_PNP
 struct resource *pnp_get_resource(struct pnp_dev *, unsigned int, unsigned int);
+#else
+static inline struct resource *pnp_get_resource(struct pnp_dev *dev, unsigned int type, unsigned int num)
+{
+       return NULL;
+}
+#endif
 
 static inline int pnp_resource_valid(struct resource *res)
 {
index ca643b13b02635bfd33bae20588418ca52ff3f3b..2b3d51c6ec9c706ae1049894340c5a00a9de169f 100644 (file)
@@ -582,6 +582,10 @@ enum rtnetlink_groups {
 #define RTNLGRP_IPV6_RULE      RTNLGRP_IPV6_RULE
        RTNLGRP_ND_USEROPT,
 #define RTNLGRP_ND_USEROPT     RTNLGRP_ND_USEROPT
+       RTNLGRP_PHONET_IFADDR,
+#define RTNLGRP_PHONET_IFADDR  RTNLGRP_PHONET_IFADDR
+       RTNLGRP_PHONET_ROUTE,
+#define RTNLGRP_PHONET_ROUTE   RTNLGRP_PHONET_ROUTE
        __RTNLGRP_MAX
 };
 #define RTNLGRP_MAX    (__RTNLGRP_MAX - 1)
index aa80ad9cbc88466e681a2d3a9e97e27889f061a9..720b688c22b678fd8cde53e3dd7a14f0c8cabbe9 100644 (file)
@@ -383,6 +383,8 @@ static inline struct sk_buff *alloc_skb_fclone(unsigned int size,
        return __alloc_skb(size, priority, 1, -1);
 }
 
+extern int skb_recycle_check(struct sk_buff *skb, int skb_size);
+
 extern struct sk_buff *skb_morph(struct sk_buff *dst, struct sk_buff *src);
 extern struct sk_buff *skb_clone(struct sk_buff *skb,
                                 gfp_t priority);
@@ -472,6 +474,37 @@ static inline int skb_queue_empty(const struct sk_buff_head *list)
        return list->next == (struct sk_buff *)list;
 }
 
+/**
+ *     skb_queue_is_last - check if skb is the last entry in the queue
+ *     @list: queue head
+ *     @skb: buffer
+ *
+ *     Returns true if @skb is the last buffer on the list.
+ */
+static inline bool skb_queue_is_last(const struct sk_buff_head *list,
+                                    const struct sk_buff *skb)
+{
+       return (skb->next == (struct sk_buff *) list);
+}
+
+/**
+ *     skb_queue_next - return the next packet in the queue
+ *     @list: queue head
+ *     @skb: current buffer
+ *
+ *     Return the next packet in @list after @skb.  It is only valid to
+ *     call this if skb_queue_is_last() evaluates to false.
+ */
+static inline struct sk_buff *skb_queue_next(const struct sk_buff_head *list,
+                                            const struct sk_buff *skb)
+{
+       /* This BUG_ON may seem severe, but if we just return then we
+        * are going to dereference garbage.
+        */
+       BUG_ON(skb_queue_is_last(list, skb));
+       return skb->next;
+}
+
 /**
  *     skb_get - reference buffer
  *     @skb: buffer to reference
@@ -660,6 +693,22 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_)
        return list_->qlen;
 }
 
+/**
+ *     __skb_queue_head_init - initialize non-spinlock portions of sk_buff_head
+ *     @list: queue to initialize
+ *
+ *     This initializes only the list and queue length aspects of
+ *     an sk_buff_head object.  This allows to initialize the list
+ *     aspects of an sk_buff_head without reinitializing things like
+ *     the spinlock.  It can also be used for on-stack sk_buff_head
+ *     objects where the spinlock is known to not be used.
+ */
+static inline void __skb_queue_head_init(struct sk_buff_head *list)
+{
+       list->prev = list->next = (struct sk_buff *)list;
+       list->qlen = 0;
+}
+
 /*
  * This function creates a split out lock class for each invocation;
  * this is needed for now since a whole lot of users of the skb-queue
@@ -671,8 +720,7 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_)
 static inline void skb_queue_head_init(struct sk_buff_head *list)
 {
        spin_lock_init(&list->lock);
-       list->prev = list->next = (struct sk_buff *)list;
-       list->qlen = 0;
+       __skb_queue_head_init(list);
 }
 
 static inline void skb_queue_head_init_class(struct sk_buff_head *list,
@@ -699,6 +747,83 @@ static inline void __skb_insert(struct sk_buff *newsk,
        list->qlen++;
 }
 
+static inline void __skb_queue_splice(const struct sk_buff_head *list,
+                                     struct sk_buff *prev,
+                                     struct sk_buff *next)
+{
+       struct sk_buff *first = list->next;
+       struct sk_buff *last = list->prev;
+
+       first->prev = prev;
+       prev->next = first;
+
+       last->next = next;
+       next->prev = last;
+}
+
+/**
+ *     skb_queue_splice - join two skb lists, this is designed for stacks
+ *     @list: the new list to add
+ *     @head: the place to add it in the first list
+ */
+static inline void skb_queue_splice(const struct sk_buff_head *list,
+                                   struct sk_buff_head *head)
+{
+       if (!skb_queue_empty(list)) {
+               __skb_queue_splice(list, (struct sk_buff *) head, head->next);
+               head->qlen += list->qlen;
+       }
+}
+
+/**
+ *     skb_queue_splice - join two skb lists and reinitialise the emptied list
+ *     @list: the new list to add
+ *     @head: the place to add it in the first list
+ *
+ *     The list at @list is reinitialised
+ */
+static inline void skb_queue_splice_init(struct sk_buff_head *list,
+                                        struct sk_buff_head *head)
+{
+       if (!skb_queue_empty(list)) {
+               __skb_queue_splice(list, (struct sk_buff *) head, head->next);
+               head->qlen += list->qlen;
+               __skb_queue_head_init(list);
+       }
+}
+
+/**
+ *     skb_queue_splice_tail - join two skb lists, each list being a queue
+ *     @list: the new list to add
+ *     @head: the place to add it in the first list
+ */
+static inline void skb_queue_splice_tail(const struct sk_buff_head *list,
+                                        struct sk_buff_head *head)
+{
+       if (!skb_queue_empty(list)) {
+               __skb_queue_splice(list, head->prev, (struct sk_buff *) head);
+               head->qlen += list->qlen;
+       }
+}
+
+/**
+ *     skb_queue_splice_tail - join two skb lists and reinitialise the emptied list
+ *     @list: the new list to add
+ *     @head: the place to add it in the first list
+ *
+ *     Each of the lists is a queue.
+ *     The list at @list is reinitialised
+ */
+static inline void skb_queue_splice_tail_init(struct sk_buff_head *list,
+                                             struct sk_buff_head *head)
+{
+       if (!skb_queue_empty(list)) {
+               __skb_queue_splice(list, head->prev, (struct sk_buff *) head);
+               head->qlen += list->qlen;
+               __skb_queue_head_init(list);
+       }
+}
+
 /**
  *     __skb_queue_after - queue a buffer at the list head
  *     @list: list to use
@@ -1448,6 +1573,15 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
                     skb != (struct sk_buff *)(queue);                          \
                     skb = tmp, tmp = skb->next)
 
+#define skb_queue_walk_from(queue, skb)                                                \
+               for (; prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \
+                    skb = skb->next)
+
+#define skb_queue_walk_from_safe(queue, skb, tmp)                              \
+               for (tmp = skb->next;                                           \
+                    skb != (struct sk_buff *)(queue);                          \
+                    skb = tmp, tmp = skb->next)
+
 #define skb_queue_reverse_walk(queue, skb) \
                for (skb = (queue)->prev;                                       \
                     prefetch(skb->prev), (skb != (struct sk_buff *)(queue));   \
index caa43b2370cb04b6b12e7aa47d398e35dbfbedb3..82fefddc5987d0fba7925c76a14f2ac52dd82caf 100644 (file)
@@ -11,7 +11,9 @@
 
 #include <linux/types.h>
 #include <linux/magic.h>
+#ifdef __KERNEL__
 #include <linux/time.h>
+#endif
 
 enum smb_protocol { 
        SMB_PROTOCOL_NONE, 
index dc5086fe7736c10f40bfbab0996b7d589ccf5bbe..20fc4bbfca42b4327c346fd1f491661838062e34 100644 (file)
@@ -190,7 +190,8 @@ struct ucred {
 #define AF_IUCV                32      /* IUCV sockets                 */
 #define AF_RXRPC       33      /* RxRPC sockets                */
 #define AF_ISDN                34      /* mISDN sockets                */
-#define AF_MAX         35      /* For now.. */
+#define AF_PHONET      35      /* Phonet sockets               */
+#define AF_MAX         36      /* For now.. */
 
 /* Protocol families, same as address families. */
 #define PF_UNSPEC      AF_UNSPEC
@@ -227,6 +228,7 @@ struct ucred {
 #define PF_IUCV                AF_IUCV
 #define PF_RXRPC       AF_RXRPC
 #define PF_ISDN                AF_ISDN
+#define PF_PHONET      AF_PHONET
 #define PF_MAX         AF_MAX
 
 /* Maximum queue length specifiable by listen.  */
@@ -295,6 +297,7 @@ struct ucred {
 #define SOL_RXRPC      272
 #define SOL_PPPOL2TP   273
 #define SOL_BLUETOOTH  274
+#define SOL_PNPIPE     275
 
 /* IPX options */
 #define IPX_TYPE       1
index fb0c215a3051a0e697d305c98067f39c25a2c790..4bc1e6b86cb21ae1b0bc3ab24fd26806e4e3445e 100644 (file)
@@ -279,6 +279,7 @@ enum xfrm_attr_type_t {
        XFRMA_POLICY_TYPE,      /* struct xfrm_userpolicy_type */
        XFRMA_MIGRATE,
        XFRMA_ALG_AEAD,         /* struct xfrm_algo_aead */
+       XFRMA_KMADDRESS,        /* struct xfrm_user_kmaddress */
        __XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
@@ -415,6 +416,15 @@ struct xfrm_user_report {
        struct xfrm_selector            sel;
 };
 
+/* Used by MIGRATE to pass addresses IKE should use to perform
+ * SA negotiation with the peer */
+struct xfrm_user_kmaddress {
+       xfrm_address_t                  local;
+       xfrm_address_t                  remote;
+       __u32                           reserved;
+       __u16                           family;
+};
+
 struct xfrm_user_migrate {
        xfrm_address_t                  old_daddr;
        xfrm_address_t                  old_saddr;
index b3d3e27c62999d08360dcb51c15430d2d93c953d..c3626c0ba9d39a4358e028c328dfe534c5393b18 100644 (file)
@@ -596,4 +596,5 @@ int p9_idpool_check(int id, struct p9_idpool *p);
 int p9_error_init(void);
 int p9_errstr2errno(char *, int);
 int p9_trans_fd_init(void);
+void p9_trans_fd_exit(void);
 #endif /* NET_9P_H */
index 0db3a4038dc0d1e8feb9f89f763203169b335b36..3ca737120a90cff4f845d8ccc66fc9173e0fcd6f 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef NET_9P_TRANSPORT_H
 #define NET_9P_TRANSPORT_H
 
+#include <linux/module.h>
+
 /**
  * enum p9_trans_status - different states of underlying transports
  * @Connected: transport is connected and healthy
@@ -91,9 +93,12 @@ struct p9_trans_module {
        int maxsize;            /* max message size of transport */
        int def;                /* this transport should be default */
        struct p9_trans * (*create)(const char *, char *, int, unsigned char);
+       struct module *owner;
 };
 
 void v9fs_register_trans(struct p9_trans_module *m);
-struct p9_trans_module *v9fs_match_trans(const substring_t *name);
-struct p9_trans_module *v9fs_default_trans(void);
+void v9fs_unregister_trans(struct p9_trans_module *m);
+struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name);
+struct p9_trans_module *v9fs_get_default_trans(void);
+void v9fs_put_trans(struct p9_trans_module *m);
 #endif /* NET_9P_TRANSPORT_H */
index 9f40c4d417d72fb3d1accae81ea64cff87d7dd45..0e85ec39b6380de904efe8c2ac0c89b3cb6f12e0 100644 (file)
@@ -363,11 +363,13 @@ struct wiphy;
  * wireless extensions but this is subject to reevaluation as soon as this
  * code is used more widely and we have a first user without wext.
  *
- * @add_virtual_intf: create a new virtual interface with the given name
+ * @add_virtual_intf: create a new virtual interface with the given name,
+ *     must set the struct wireless_dev's iftype.
  *
  * @del_virtual_intf: remove the virtual interface determined by ifindex.
  *
- * @change_virtual_intf: change type of virtual interface
+ * @change_virtual_intf: change type/configuration of virtual interface,
+ *     keep the struct wireless_dev's iftype updated.
  *
  * @add_key: add a key with the given parameters. @mac_addr will be %NULL
  *     when adding a group key.
index 228b2477ceecde908e699c31d47efc247181bd3f..b45a5e4fcadd83545fb48b5b9a9daec347811f71 100644 (file)
@@ -47,6 +47,8 @@ struct flowi {
 #define fl4_scope      nl_u.ip4_u.scope
 
        __u8    proto;
+       __u8    flags;
+#define FLOWI_FLAG_ANYSRC 0x01
        union {
                struct {
                        __be16  sport;
index b31399e1fd83a3c3230d1b2c516c359675ef0f36..6048579d0b2433edf27132f086cfcc7509dd752d 100644 (file)
@@ -190,10 +190,6 @@ const char *escape_essid(const char *essid, u8 essid_len);
 #endif
 #include <net/iw_handler.h>    /* new driver API */
 
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E       /* Port Access Entity (IEEE 802.1X) */
-#endif                         /* ETH_P_PAE */
-
 #define ETH_P_PREAUTH 0x88C7   /* IEEE 802.11i pre-authentication */
 
 #ifndef ETH_P_80211_RAW
index 643e26be058ef2e91640fa59c1ac1e42df6e8590..de0ecc71cf0388d944ec0a032b7ffe8453324a95 100644 (file)
@@ -24,7 +24,6 @@
 #include <net/flow.h>
 #include <net/sock.h>
 #include <net/request_sock.h>
-#include <net/route.h>
 #include <net/netns/hash.h>
 
 /** struct ip_options - IP Options
@@ -62,8 +61,8 @@ struct inet_request_sock {
        struct request_sock     req;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
        u16                     inet6_rsk_offset;
-       /* 2 bytes hole, try to pack */
 #endif
+       __be16                  loc_port;
        __be32                  loc_addr;
        __be32                  rmt_addr;
        __be16                  rmt_port;
@@ -73,7 +72,8 @@ struct inet_request_sock {
                                sack_ok    : 1,
                                wscale_ok  : 1,
                                ecn_ok     : 1,
-                               acked      : 1;
+                               acked      : 1,
+                               no_srccheck: 1;
        struct ip_options       *opt;
 };
 
@@ -129,7 +129,8 @@ struct inet_sock {
                                is_icsk:1,
                                freebind:1,
                                hdrincl:1,
-                               mc_loop:1;
+                               mc_loop:1,
+                               transparent:1;
        int                     mc_index;
        __be32                  mc_addr;
        struct ip_mc_socklist   *mc_list;
@@ -194,12 +195,6 @@ static inline int inet_sk_ehashfn(const struct sock *sk)
        return inet_ehashfn(net, laddr, lport, faddr, fport);
 }
 
-
-static inline int inet_iif(const struct sk_buff *skb)
-{
-       return skb->rtable->rt_iif;
-}
-
 static inline struct request_sock *inet_reqsk_alloc(struct request_sock_ops *ops)
 {
        struct request_sock *req = reqsk_alloc(ops);
@@ -210,4 +205,9 @@ static inline struct request_sock *inet_reqsk_alloc(struct request_sock_ops *ops
        return req;
 }
 
+static inline __u8 inet_sk_flowi_flags(const struct sock *sk)
+{
+       return inet_sk(sk)->transparent ? FLOWI_FLAG_ANYSRC : 0;
+}
+
 #endif /* _INET_SOCK_H */
index 91324908fccd367953bcce47aeb537afbd242f2e..80e4977631b8b18ba67e44024895fee03adbe7f9 100644 (file)
@@ -128,7 +128,8 @@ struct inet_timewait_sock {
        __be16                  tw_dport;
        __u16                   tw_num;
        /* And these are ours. */
-       __u8                    tw_ipv6only:1;
+       __u8                    tw_ipv6only:1,
+                               tw_transparent:1;
        /* 15 bits hole, try to pack */
        __u16                   tw_ipv6_offset;
        unsigned long           tw_ttd;
index 250e6ef025a460e16e58636645a71cd51dbce887..d678ea3d474a8ff5771272fe3a587ef6d0ade55d 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <net/inet_sock.h>
 #include <net/snmp.h>
+#include <net/flow.h>
 
 struct sock;
 
@@ -140,12 +141,20 @@ static inline void ip_tr_mc_map(__be32 addr, char *buf)
 
 struct ip_reply_arg {
        struct kvec iov[1];   
+       int         flags;
        __wsum      csum;
        int         csumoffset; /* u16 offset of csum in iov[0].iov_base */
                                /* -1 if not needed */ 
        int         bound_dev_if;
 }; 
 
+#define IP_REPLY_ARG_NOSRCCHECK 1
+
+static inline __u8 ip_reply_arg_flowi_flags(const struct ip_reply_arg *arg)
+{
+       return (arg->flags & IP_REPLY_ARG_NOSRCCHECK) ? FLOWI_FLAG_ANYSRC : 0;
+}
+
 void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *arg,
                   unsigned int len); 
 
index 33e2ac6ceb3ec5605613b8a5ac06a7f24a36a599..0b2071d9326de8c059ed814848247c50d24535cb 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <net/checksum.h>
 #include <linux/netfilter.h>           /* for union nf_inet_addr */
+#include <linux/ip.h>
 #include <linux/ipv6.h>                        /* for struct ipv6hdr */
 #include <net/ipv6.h>                  /* for ipv6_addr_copy */
 
index 113028fb8f6610c912e57326dbaf6f4bd1c5c649..dfa7ae3c5607fa78f3bbfe7605d333f1d11503cc 100644 (file)
@@ -576,6 +576,8 @@ extern int ip6_mc_msfilter(struct sock *sk, struct group_filter *gsf);
 extern int ip6_mc_msfget(struct sock *sk, struct group_filter *gsf,
                         struct group_filter __user *optval,
                         int __user *optlen);
+extern unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr,
+                                   const struct in6_addr *daddr, u32 rnd);
 
 #ifdef CONFIG_PROC_FS
 extern int  ac6_proc_init(struct net *net);
index 003e4a03874e0012b9fbd597a792140cd59ac128..f5f5b1ff158468e9a1e1605476a34a9e3031f8f4 100644 (file)
@@ -1800,4 +1800,72 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw,
 struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
                                         const u8 *addr);
 
+
+/* Rate control API */
+/**
+ * struct rate_selection - rate information for/from rate control algorithms
+ *
+ * @rate_idx: selected transmission rate index
+ * @nonerp_idx: Non-ERP rate to use instead if ERP cannot be used
+ * @probe_idx: rate for probing (or -1)
+ * @max_rate_idx: maximum rate index that can be used, this is
+ *     input to the algorithm and will be enforced
+ */
+struct rate_selection {
+       s8 rate_idx, nonerp_idx, probe_idx, max_rate_idx;
+};
+
+struct rate_control_ops {
+       struct module *module;
+       const char *name;
+       void *(*alloc)(struct ieee80211_hw *hw, struct dentry *debugfsdir);
+       void (*clear)(void *priv);
+       void (*free)(void *priv);
+
+       void *(*alloc_sta)(void *priv, struct ieee80211_sta *sta, gfp_t gfp);
+       void (*rate_init)(void *priv, struct ieee80211_supported_band *sband,
+                         struct ieee80211_sta *sta, void *priv_sta);
+       void (*free_sta)(void *priv, struct ieee80211_sta *sta,
+                        void *priv_sta);
+
+       void (*tx_status)(void *priv, struct ieee80211_supported_band *sband,
+                         struct ieee80211_sta *sta, void *priv_sta,
+                         struct sk_buff *skb);
+       void (*get_rate)(void *priv, struct ieee80211_supported_band *sband,
+                        struct ieee80211_sta *sta, void *priv_sta,
+                        struct sk_buff *skb,
+                        struct rate_selection *sel);
+
+       void (*add_sta_debugfs)(void *priv, void *priv_sta,
+                               struct dentry *dir);
+       void (*remove_sta_debugfs)(void *priv, void *priv_sta);
+};
+
+static inline int rate_supported(struct ieee80211_sta *sta,
+                                enum ieee80211_band band,
+                                int index)
+{
+       return (sta == NULL || sta->supp_rates[band] & BIT(index));
+}
+
+static inline s8
+rate_lowest_index(struct ieee80211_supported_band *sband,
+                 struct ieee80211_sta *sta)
+{
+       int i;
+
+       for (i = 0; i < sband->n_bitrates; i++)
+               if (rate_supported(sta, sband->band, i))
+                       return i;
+
+       /* warn when we cannot find a rate. */
+       WARN_ON(1);
+
+       return 0;
+}
+
+
+int ieee80211_rate_control_register(struct rate_control_ops *ops);
+void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
+
 #endif /* MAC80211_H */
index 76c43ff38f64178d98d6d911bcd9651a4969075c..3643bbb8e585e4018cbd66606d64c12a7edf84ac 100644 (file)
@@ -698,7 +698,7 @@ static inline int nla_len(const struct nlattr *nla)
  */
 static inline int nla_ok(const struct nlattr *nla, int remaining)
 {
-       return remaining >= sizeof(*nla) &&
+       return remaining >= (int) sizeof(*nla) &&
               nla->nla_len >= sizeof(*nla) &&
               nla->nla_len <= remaining;
 }
diff --git a/include/net/phonet/gprs.h b/include/net/phonet/gprs.h
new file mode 100644 (file)
index 0000000..928daf5
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * File: pep_gprs.h
+ *
+ * GPRS over Phonet pipe end point socket
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef NET_PHONET_GPRS_H
+#define NET_PHONET_GPRS_H
+
+struct sock;
+struct sk_buff;
+
+int pep_writeable(struct sock *sk);
+int pep_write(struct sock *sk, struct sk_buff *skb);
+struct sk_buff *pep_read(struct sock *sk);
+
+int gprs_attach(struct sock *sk);
+void gprs_detach(struct sock *sk);
+
+#endif
diff --git a/include/net/phonet/pep.h b/include/net/phonet/pep.h
new file mode 100644 (file)
index 0000000..fcd7930
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * File: pep.h
+ *
+ * Phonet Pipe End Point sockets definitions
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef NET_PHONET_PEP_H
+#define NET_PHONET_PEP_H
+
+struct pep_sock {
+       struct pn_sock          pn_sk;
+
+       /* XXX: union-ify listening vs connected stuff ? */
+       /* Listening socket stuff: */
+       struct hlist_head       ackq;
+       struct hlist_head       hlist;
+
+       /* Connected socket stuff: */
+       struct sock             *listener;
+       struct sk_buff_head     ctrlreq_queue;
+#define PNPIPE_CTRLREQ_MAX     10
+       int                     ifindex;
+       u16                     peer_type;      /* peer type/subtype */
+       u8                      pipe_handle;
+
+       u8                      rx_credits;
+       u8                      tx_credits;
+       u8                      rx_fc;  /* RX flow control */
+       u8                      tx_fc;  /* TX flow control */
+       u8                      init_enable;    /* auto-enable at creation */
+};
+
+static inline struct pep_sock *pep_sk(struct sock *sk)
+{
+       return (struct pep_sock *)sk;
+}
+
+extern const struct proto_ops phonet_stream_ops;
+
+/* Pipe protocol definitions */
+struct pnpipehdr {
+       u8                      utid; /* transaction ID */
+       u8                      message_id;
+       u8                      pipe_handle;
+       union {
+               u8              state_after_connect;    /* connect request */
+               u8              state_after_reset;      /* reset request */
+               u8              error_code;             /* any response */
+               u8              pep_type;               /* status indication */
+               u8              data[1];
+       };
+};
+#define other_pep_type         data[1]
+
+static inline struct pnpipehdr *pnp_hdr(struct sk_buff *skb)
+{
+       return (struct pnpipehdr *)skb_transport_header(skb);
+}
+
+#define MAX_PNPIPE_HEADER (MAX_PHONET_HEADER + 4)
+
+enum {
+       PNS_PIPE_DATA = 0x20,
+
+       PNS_PEP_CONNECT_REQ = 0x40,
+       PNS_PEP_CONNECT_RESP,
+       PNS_PEP_DISCONNECT_REQ,
+       PNS_PEP_DISCONNECT_RESP,
+       PNS_PEP_RESET_REQ,
+       PNS_PEP_RESET_RESP,
+       PNS_PEP_ENABLE_REQ,
+       PNS_PEP_ENABLE_RESP,
+       PNS_PEP_CTRL_REQ,
+       PNS_PEP_CTRL_RESP,
+       PNS_PEP_DISABLE_REQ = 0x4C,
+       PNS_PEP_DISABLE_RESP,
+
+       PNS_PEP_STATUS_IND = 0x60,
+       PNS_PIPE_CREATED_IND,
+       PNS_PIPE_RESET_IND = 0x63,
+       PNS_PIPE_ENABLED_IND,
+       PNS_PIPE_REDIRECTED_IND,
+       PNS_PIPE_DISABLED_IND = 0x66,
+};
+
+#define PN_PIPE_INVALID_HANDLE 0xff
+#define PN_PEP_TYPE_COMMON     0x00
+
+/* Phonet pipe status indication */
+enum {
+       PN_PEP_IND_FLOW_CONTROL,
+       PN_PEP_IND_ID_MCFC_GRANT_CREDITS,
+};
+
+/* Phonet pipe error codes */
+enum {
+       PN_PIPE_NO_ERROR,
+       PN_PIPE_ERR_INVALID_PARAM,
+       PN_PIPE_ERR_INVALID_HANDLE,
+       PN_PIPE_ERR_INVALID_CTRL_ID,
+       PN_PIPE_ERR_NOT_ALLOWED,
+       PN_PIPE_ERR_PEP_IN_USE,
+       PN_PIPE_ERR_OVERLOAD,
+       PN_PIPE_ERR_DEV_DISCONNECTED,
+       PN_PIPE_ERR_TIMEOUT,
+       PN_PIPE_ERR_ALL_PIPES_IN_USE,
+       PN_PIPE_ERR_GENERAL,
+       PN_PIPE_ERR_NOT_SUPPORTED,
+};
+
+/* Phonet pipe states */
+enum {
+       PN_PIPE_DISABLE,
+       PN_PIPE_ENABLE,
+};
+
+/* Phonet pipe sub-block types */
+enum {
+       PN_PIPE_SB_CREATE_REQ_PEP_SUB_TYPE,
+       PN_PIPE_SB_CONNECT_REQ_PEP_SUB_TYPE,
+       PN_PIPE_SB_REDIRECT_REQ_PEP_SUB_TYPE,
+       PN_PIPE_SB_NEGOTIATED_FC,
+       PN_PIPE_SB_REQUIRED_FC_TX,
+       PN_PIPE_SB_PREFERRED_FC_RX,
+};
+
+/* Phonet pipe flow control models */
+enum {
+       PN_NO_FLOW_CONTROL,
+       PN_LEGACY_FLOW_CONTROL,
+       PN_ONE_CREDIT_FLOW_CONTROL,
+       PN_MULTI_CREDIT_FLOW_CONTROL,
+};
+
+#define pn_flow_safe(fc) ((fc) >> 1)
+
+/* Phonet pipe flow control states */
+enum {
+       PEP_IND_EMPTY,
+       PEP_IND_BUSY,
+       PEP_IND_READY,
+};
+
+#endif
diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
new file mode 100644 (file)
index 0000000..d4e7250
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * File: af_phonet.h
+ *
+ * Phonet sockets kernel definitions
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef AF_PHONET_H
+#define AF_PHONET_H
+
+/*
+ * The lower layers may not require more space, ever. Make sure it's
+ * enough.
+ */
+#define MAX_PHONET_HEADER      8
+
+/*
+ * Every Phonet* socket has this structure first in its
+ * protocol-specific structure under name c.
+ */
+struct pn_sock {
+       struct sock     sk;
+       u16             sobject;
+       u8              resource;
+};
+
+static inline struct pn_sock *pn_sk(struct sock *sk)
+{
+       return (struct pn_sock *)sk;
+}
+
+extern const struct proto_ops phonet_dgram_ops;
+
+struct sock *pn_find_sock_by_sa(const struct sockaddr_pn *sa);
+void phonet_get_local_port_range(int *min, int *max);
+void pn_sock_hash(struct sock *sk);
+void pn_sock_unhash(struct sock *sk);
+int pn_sock_get_port(struct sock *sk, unsigned short sport);
+
+int pn_skb_send(struct sock *sk, struct sk_buff *skb,
+               const struct sockaddr_pn *target);
+
+static inline struct phonethdr *pn_hdr(struct sk_buff *skb)
+{
+       return (struct phonethdr *)skb_network_header(skb);
+}
+
+static inline struct phonetmsg *pn_msg(struct sk_buff *skb)
+{
+       return (struct phonetmsg *)skb_transport_header(skb);
+}
+
+/*
+ * Get the other party's sockaddr from received skb. The skb begins
+ * with a Phonet header.
+ */
+static inline
+void pn_skb_get_src_sockaddr(struct sk_buff *skb, struct sockaddr_pn *sa)
+{
+       struct phonethdr *ph = pn_hdr(skb);
+       u16 obj = pn_object(ph->pn_sdev, ph->pn_sobj);
+
+       sa->spn_family = AF_PHONET;
+       pn_sockaddr_set_object(sa, obj);
+       pn_sockaddr_set_resource(sa, ph->pn_res);
+       memset(sa->spn_zero, 0, sizeof(sa->spn_zero));
+}
+
+static inline
+void pn_skb_get_dst_sockaddr(struct sk_buff *skb, struct sockaddr_pn *sa)
+{
+       struct phonethdr *ph = pn_hdr(skb);
+       u16 obj = pn_object(ph->pn_rdev, ph->pn_robj);
+
+       sa->spn_family = AF_PHONET;
+       pn_sockaddr_set_object(sa, obj);
+       pn_sockaddr_set_resource(sa, ph->pn_res);
+       memset(sa->spn_zero, 0, sizeof(sa->spn_zero));
+}
+
+/* Protocols in Phonet protocol family. */
+struct phonet_protocol {
+       const struct proto_ops  *ops;
+       struct proto            *prot;
+       int                     sock_type;
+};
+
+int phonet_proto_register(int protocol, struct phonet_protocol *pp);
+void phonet_proto_unregister(int protocol, struct phonet_protocol *pp);
+
+int phonet_sysctl_init(void);
+void phonet_sysctl_exit(void);
+void phonet_netlink_register(void);
+int isi_register(void);
+void isi_unregister(void);
+
+#endif
diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
new file mode 100644 (file)
index 0000000..bbd2a83
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * File: pn_dev.h
+ *
+ * Phonet network device
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef PN_DEV_H
+#define PN_DEV_H
+
+struct phonet_device_list {
+       struct list_head list;
+       spinlock_t lock;
+};
+
+extern struct phonet_device_list pndevs;
+
+struct phonet_device {
+       struct list_head list;
+       struct net_device *netdev;
+       DECLARE_BITMAP(addrs, 64);
+};
+
+void phonet_device_init(void);
+void phonet_device_exit(void);
+struct net_device *phonet_device_get(struct net *net);
+
+int phonet_address_add(struct net_device *dev, u8 addr);
+int phonet_address_del(struct net_device *dev, u8 addr);
+u8 phonet_address_get(struct net_device *dev, u8 addr);
+int phonet_address_lookup(u8 addr);
+
+#define PN_NO_ADDR     0xff
+
+#endif
index b786a5b09253c0687739033f3eb51471a16d29a6..4082f39f507916c5002d7677831da8aff0e9013f 100644 (file)
@@ -90,10 +90,7 @@ extern void __qdisc_run(struct Qdisc *q);
 
 static inline void qdisc_run(struct Qdisc *q)
 {
-       struct netdev_queue *txq = q->dev_queue;
-
-       if (!netif_tx_queue_stopped(txq) &&
-           !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
+       if (!test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
                __qdisc_run(q);
 }
 
index 4f0d8c14736cba916799c7793848d8d42595483f..4e8cae0e58415191845543b39717dc138d024194 100644 (file)
@@ -27,7 +27,7 @@
 #include <net/dst.h>
 #include <net/inetpeer.h>
 #include <net/flow.h>
-#include <net/sock.h>
+#include <net/inet_sock.h>
 #include <linux/in_route.h>
 #include <linux/rtnetlink.h>
 #include <linux/route.h>
@@ -161,6 +161,10 @@ static inline int ip_route_connect(struct rtable **rp, __be32 dst,
 
        int err;
        struct net *net = sock_net(sk);
+
+       if (inet_sk(sk)->transparent)
+               fl.flags |= FLOWI_FLAG_ANYSRC;
+
        if (!dst || !src) {
                err = __ip_route_output_key(net, rp, &fl);
                if (err)
@@ -204,4 +208,9 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt)
        return rt->peer;
 }
 
+static inline int inet_iif(const struct sk_buff *skb)
+{
+       return skb->rtable->rt_iif;
+}
+
 #endif /* _ROUTE_H */
index e5569625d2a50db02b290a5d9c339808be17a86b..3fe49d808957309f29f1cb9532892fc06e936f2e 100644 (file)
@@ -53,6 +53,7 @@ struct Qdisc
        atomic_t                refcnt;
        unsigned long           state;
        struct sk_buff          *gso_skb;
+       struct sk_buff_head     requeue;
        struct sk_buff_head     q;
        struct netdev_queue     *dev_queue;
        struct Qdisc            *next_sched;
index 17b932b8a55a771f12248a7909f07950552bf4d8..703305d00365ff86460315c5490b3417b36ce2f1 100644 (file)
@@ -406,10 +406,7 @@ struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id);
 
 /* A macro to walk a list of skbs.  */
 #define sctp_skb_for_each(pos, head, tmp) \
-for (pos = (head)->next;\
-     tmp = (pos)->next, pos != ((struct sk_buff *)(head));\
-     pos = tmp)
-
+       skb_queue_walk_safe(head, pos, tmp)
 
 /* A helper to append an entire skb list (list) to another (head). */
 static inline void sctp_skb_list_tail(struct sk_buff_head *list,
@@ -420,10 +417,7 @@ static inline void sctp_skb_list_tail(struct sk_buff_head *list,
        sctp_spin_lock_irqsave(&head->lock, flags);
        sctp_spin_lock(&list->lock);
 
-       list_splice((struct list_head *)list, (struct list_head *)head->prev);
-
-       head->qlen += list->qlen;
-       list->qlen = 0;
+       skb_queue_splice_tail_init(list, head);
 
        sctp_spin_unlock(&list->lock);
        sctp_spin_unlock_irqrestore(&head->lock, flags);
index 24811732bdb2515977d7defbb5b9ce548dcea315..029a54a0239695894656d99c0342f0ed37b0ce61 100644 (file)
@@ -227,6 +227,9 @@ struct sctp_chunk *sctp_make_abort_violation(const struct sctp_association *,
                                   const struct sctp_chunk *,
                                   const __u8 *,
                                   const size_t );
+struct sctp_chunk *sctp_make_violation_paramlen(const struct sctp_association *,
+                                  const struct sctp_chunk *,
+                                  struct sctp_paramhdr *);
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *,
                                  const struct sctp_transport *,
                                  const void *payload,
index ab1c472ea75375a45dead4368cabd96b30941b2e..94c62e4ddea9915eae413745c900f6b03645d1ba 100644 (file)
@@ -731,20 +731,23 @@ struct sctp_chunk {
         */
        struct sk_buff *auth_chunk;
 
-       __u8 rtt_in_progress;   /* Is this chunk used for RTT calculation? */
-       __u8 resent;            /* Has this chunk ever been retransmitted. */
-       __u8 has_tsn;           /* Does this chunk have a TSN yet? */
-       __u8 has_ssn;           /* Does this chunk have a SSN yet? */
-       __u8 singleton;         /* Was this the only chunk in the packet? */
-       __u8 end_of_packet;     /* Was this the last chunk in the packet? */
-       __u8 ecn_ce_done;       /* Have we processed the ECN CE bit? */
-       __u8 pdiscard;          /* Discard the whole packet now? */
-       __u8 tsn_gap_acked;     /* Is this chunk acked by a GAP ACK? */
-       __s8 fast_retransmit;    /* Is this chunk fast retransmitted? */
-       __u8 tsn_missing_report; /* Data chunk missing counter. */
-       __u8 data_accepted;     /* At least 1 chunk in this packet accepted */
-       __u8 auth;              /* IN: was auth'ed | OUT: needs auth */
-       __u8 has_asconf;        /* IN: have seen an asconf before */
+#define SCTP_CAN_FRTX 0x0
+#define SCTP_NEED_FRTX 0x1
+#define SCTP_DONT_FRTX 0x2
+       __u16   rtt_in_progress:1,      /* This chunk used for RTT calc? */
+               resent:1,               /* Has this chunk ever been resent. */
+               has_tsn:1,              /* Does this chunk have a TSN yet? */
+               has_ssn:1,              /* Does this chunk have a SSN yet? */
+               singleton:1,            /* Only chunk in the packet? */
+               end_of_packet:1,        /* Last chunk in the packet? */
+               ecn_ce_done:1,          /* Have we processed the ECN CE bit? */
+               pdiscard:1,             /* Discard the whole packet now? */
+               tsn_gap_acked:1,        /* Is this chunk acked by a GAP ACK? */
+               data_accepted:1,        /* At least 1 chunk accepted */
+               auth:1,                 /* IN: was auth'ed | OUT: needs auth */
+               has_asconf:1,           /* IN: have seen an asconf before */
+               tsn_missing_report:2,   /* Data chunk missing counter. */
+               fast_retransmit:2;      /* Is this chunk fast retransmitted? */
 };
 
 void sctp_chunk_hold(struct sctp_chunk *);
@@ -1225,7 +1228,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw, int len,
 
 sctp_scope_t sctp_scope(const union sctp_addr *);
 int sctp_in_scope(const union sctp_addr *addr, const sctp_scope_t scope);
-int sctp_is_any(const union sctp_addr *addr);
+int sctp_is_any(struct sock *sk, const union sctp_addr *addr);
 int sctp_addr_is_valid(const union sctp_addr *addr);
 
 
index ea815723d414c0904169a70370597950ae143d4f..f6cc34143154759795f52e51575ec2d00b883114 100644 (file)
@@ -976,6 +976,7 @@ static inline void tcp_openreq_init(struct request_sock *req,
        ireq->acked = 0;
        ireq->ecn_ok = 0;
        ireq->rmt_port = tcp_hdr(skb)->source;
+       ireq->loc_port = tcp_hdr(skb)->dest;
 }
 
 extern void tcp_enter_memory_pressure(struct sock *sk);
@@ -1181,49 +1182,45 @@ static inline void tcp_write_queue_purge(struct sock *sk)
 
 static inline struct sk_buff *tcp_write_queue_head(struct sock *sk)
 {
-       struct sk_buff *skb = sk->sk_write_queue.next;
-       if (skb == (struct sk_buff *) &sk->sk_write_queue)
-               return NULL;
-       return skb;
+       return skb_peek(&sk->sk_write_queue);
 }
 
 static inline struct sk_buff *tcp_write_queue_tail(struct sock *sk)
 {
-       struct sk_buff *skb = sk->sk_write_queue.prev;
-       if (skb == (struct sk_buff *) &sk->sk_write_queue)
-               return NULL;
-       return skb;
+       return skb_peek_tail(&sk->sk_write_queue);
 }
 
 static inline struct sk_buff *tcp_write_queue_next(struct sock *sk, struct sk_buff *skb)
 {
-       return skb->next;
+       return skb_queue_next(&sk->sk_write_queue, skb);
 }
 
 #define tcp_for_write_queue(skb, sk)                                   \
-               for (skb = (sk)->sk_write_queue.next;                   \
-                    (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
-                    skb = skb->next)
+       skb_queue_walk(&(sk)->sk_write_queue, skb)
 
 #define tcp_for_write_queue_from(skb, sk)                              \
-               for (; (skb != (struct sk_buff *)&(sk)->sk_write_queue);\
-                    skb = skb->next)
+       skb_queue_walk_from(&(sk)->sk_write_queue, skb)
 
 #define tcp_for_write_queue_from_safe(skb, tmp, sk)                    \
-               for (tmp = skb->next;                                   \
-                    (skb != (struct sk_buff *)&(sk)->sk_write_queue);  \
-                    skb = tmp, tmp = skb->next)
+       skb_queue_walk_from_safe(&(sk)->sk_write_queue, skb, tmp)
 
 static inline struct sk_buff *tcp_send_head(struct sock *sk)
 {
        return sk->sk_send_head;
 }
 
+static inline bool tcp_skb_is_last(const struct sock *sk,
+                                  const struct sk_buff *skb)
+{
+       return skb_queue_is_last(&sk->sk_write_queue, skb);
+}
+
 static inline void tcp_advance_send_head(struct sock *sk, struct sk_buff *skb)
 {
-       sk->sk_send_head = skb->next;
-       if (sk->sk_send_head == (struct sk_buff *)&sk->sk_write_queue)
+       if (tcp_skb_is_last(sk, skb))
                sk->sk_send_head = NULL;
+       else
+               sk->sk_send_head = tcp_write_queue_next(sk, skb);
 }
 
 static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unlinked)
@@ -1268,12 +1265,12 @@ static inline void tcp_insert_write_queue_after(struct sk_buff *skb,
        __skb_queue_after(&sk->sk_write_queue, skb, buff);
 }
 
-/* Insert skb between prev and next on the write queue of sk.  */
+/* Insert new before skb on the write queue of sk.  */
 static inline void tcp_insert_write_queue_before(struct sk_buff *new,
                                                  struct sk_buff *skb,
                                                  struct sock *sk)
 {
-       __skb_insert(new, skb->prev, skb, &sk->sk_write_queue);
+       __skb_queue_before(&sk->sk_write_queue, skb, new);
 
        if (sk->sk_send_head == skb)
                sk->sk_send_head = new;
@@ -1284,12 +1281,6 @@ static inline void tcp_unlink_write_queue(struct sk_buff *skb, struct sock *sk)
        __skb_unlink(skb, &sk->sk_write_queue);
 }
 
-static inline int tcp_skb_is_last(const struct sock *sk,
-                                 const struct sk_buff *skb)
-{
-       return skb->next == (struct sk_buff *)&sk->sk_write_queue;
-}
-
 static inline int tcp_write_queue_empty(struct sock *sk)
 {
        return skb_queue_empty(&sk->sk_write_queue);
index addcdc67234c63dd6afc714a8b580dda02c28888..d38f6f2419f95114199ccf0034211cc72fa3a308 100644 (file)
@@ -148,6 +148,10 @@ extern int         udp_lib_setsockopt(struct sock *sk, int level, int optname,
                                   char __user *optval, int optlen,
                                   int (*push_pending_frames)(struct sock *));
 
+extern struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
+                                   __be32 daddr, __be16 dport,
+                                   int dif);
+
 DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6);
 
 /* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */
index e4378cc6bf8e5d61cdefad12aa8c7fe523fe3172..721efb363db73cd0bb06270e5c1463a6e7ffe930 100644 (file)
@@ -223,9 +223,11 @@ struct wiphy {
  * the netdev.)
  *
  * @wiphy: pointer to hardware description
+ * @iftype: interface type
  */
 struct wireless_dev {
        struct wiphy *wiphy;
+       enum nl80211_iftype iftype;
 
        /* private to the generic wireless code */
        struct list_head list;
@@ -328,6 +330,15 @@ extern int ieee80211_frequency_to_channel(int freq);
  */
 extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
                                                         int freq);
+/**
+ * ieee80211_get_channel - get channel struct from wiphy for specified frequency
+ */
+static inline struct ieee80211_channel *
+ieee80211_get_channel(struct wiphy *wiphy, int freq)
+{
+       return __ieee80211_get_channel(wiphy, freq);
+}
+
 /**
  * __regulatory_hint - hint to the wireless core a regulatory domain
  * @wiphy: if a driver is providing the hint this is the driver's very
@@ -380,13 +391,4 @@ extern int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
  */
 extern int regulatory_hint(struct wiphy *wiphy,
                const char *alpha2, struct ieee80211_regdomain *rd);
-
-/**
- * ieee80211_get_channel - get channel struct from wiphy for specified frequency
- */
-static inline struct ieee80211_channel *
-ieee80211_get_channel(struct wiphy *wiphy, int freq)
-{
-       return __ieee80211_get_channel(wiphy, freq);
-}
 #endif /* __NET_WIRELESS_H */
index 4bb94992b5fab56e269ac4869393aeaa3d0f9b1c..11c890ad8ebb83fad2aebbebbcd49a2c00a1b261 100644 (file)
@@ -117,12 +117,21 @@ extern struct mutex xfrm_cfg_mutex;
       metrics. Plus, it will be made via sk->sk_dst_cache. Solved.
  */
 
+struct xfrm_state_walk {
+       struct list_head        all;
+       u8                      state;
+       union {
+               u8              dying;
+               u8              proto;
+       };
+       u32                     seq;
+};
+
 /* Full description of state of transformer. */
 struct xfrm_state
 {
-       struct list_head        all;
        union {
-               struct list_head        gclist;
+               struct hlist_node       gclist;
                struct hlist_node       bydst;
        };
        struct hlist_node       bysrc;
@@ -136,12 +145,8 @@ struct xfrm_state
 
        u32                     genid;
 
-       /* Key manger bits */
-       struct {
-               u8              state;
-               u8              dying;
-               u32             seq;
-       } km;
+       /* Key manager bits */
+       struct xfrm_state_walk  km;
 
        /* Parameters of this state. */
        struct {
@@ -449,10 +454,20 @@ struct xfrm_tmpl
 
 #define XFRM_MAX_DEPTH         6
 
+struct xfrm_policy_walk_entry {
+       struct list_head        all;
+       u8                      dead;
+};
+
+struct xfrm_policy_walk {
+       struct xfrm_policy_walk_entry walk;
+       u8 type;
+       u32 seq;
+};
+
 struct xfrm_policy
 {
        struct xfrm_policy      *next;
-       struct list_head        bytype;
        struct hlist_node       bydst;
        struct hlist_node       byidx;
 
@@ -467,17 +482,23 @@ struct xfrm_policy
        struct xfrm_lifetime_cfg lft;
        struct xfrm_lifetime_cur curlft;
        struct dst_entry       *bundles;
-       u16                     family;
+       struct xfrm_policy_walk_entry walk;
        u8                      type;
        u8                      action;
        u8                      flags;
-       u8                      dead;
        u8                      xfrm_nr;
-       /* XXX 1 byte hole, try to pack */
+       u16                     family;
        struct xfrm_sec_ctx     *security;
        struct xfrm_tmpl        xfrm_vec[XFRM_MAX_DEPTH];
 };
 
+struct xfrm_kmaddress {
+       xfrm_address_t          local;
+       xfrm_address_t          remote;
+       u32                     reserved;
+       u16                     family;
+};
+
 struct xfrm_migrate {
        xfrm_address_t          old_daddr;
        xfrm_address_t          old_saddr;
@@ -517,7 +538,7 @@ struct xfrm_mgr
        int                     (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
        int                     (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c);
        int                     (*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr);
-       int                     (*migrate)(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles);
+       int                     (*migrate)(struct xfrm_selector *sel, u8 dir, u8 type, struct xfrm_migrate *m, int num_bundles, struct xfrm_kmaddress *k);
 };
 
 extern int xfrm_register_km(struct xfrm_mgr *km);
@@ -1245,18 +1266,6 @@ struct xfrm6_tunnel {
        int priority;
 };
 
-struct xfrm_state_walk {
-       struct xfrm_state *state;
-       int count;
-       u8 proto;
-};
-
-struct xfrm_policy_walk {
-       struct xfrm_policy *policy;
-       int count;
-       u8 type, cur_type;
-};
-
 extern void xfrm_init(void);
 extern void xfrm4_init(void);
 extern void xfrm_state_init(void);
@@ -1281,13 +1290,7 @@ static inline void xfrm6_fini(void)
 extern int xfrm_proc_init(void);
 #endif
 
-static inline void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
-{
-       walk->proto = proto;
-       walk->state = NULL;
-       walk->count = 0;
-}
-
+extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto);
 extern int xfrm_state_walk(struct xfrm_state_walk *walk,
                           int (*func)(struct xfrm_state *, int, void*), void *);
 extern void xfrm_state_walk_done(struct xfrm_state_walk *walk);
@@ -1414,24 +1417,10 @@ static inline int xfrm4_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
 
 struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);
 
-static inline void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type)
-{
-       walk->cur_type = XFRM_POLICY_TYPE_MAIN;
-       walk->type = type;
-       walk->policy = NULL;
-       walk->count = 0;
-}
-
-static inline void xfrm_policy_walk_done(struct xfrm_policy_walk *walk)
-{
-       if (walk->policy != NULL) {
-               xfrm_pol_put(walk->policy);
-               walk->policy = NULL;
-       }
-}
-
+extern void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type);
 extern int xfrm_policy_walk(struct xfrm_policy_walk *walk,
        int (*func)(struct xfrm_policy *, int, int, void*), void *);
+extern void xfrm_policy_walk_done(struct xfrm_policy_walk *walk);
 int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);
 struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
                                          struct xfrm_selector *sel,
@@ -1450,12 +1439,14 @@ extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
 
 #ifdef CONFIG_XFRM_MIGRATE
 extern int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
-                     struct xfrm_migrate *m, int num_bundles);
+                     struct xfrm_migrate *m, int num_bundles,
+                     struct xfrm_kmaddress *k);
 extern struct xfrm_state * xfrm_migrate_state_find(struct xfrm_migrate *m);
 extern struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x,
                                              struct xfrm_migrate *m);
 extern int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
-                       struct xfrm_migrate *m, int num_bundles);
+                       struct xfrm_migrate *m, int num_bundles,
+                       struct xfrm_kmaddress *k);
 #endif
 
 extern wait_queue_head_t km_waitq;
index 5c40cc537d4cc625a9ad94d76190405c52694379..192f8716aa9eba82b1ebdd6555090e54d3fcb279 100644 (file)
@@ -308,6 +308,20 @@ struct scsi_lun {
        __u8 scsi_lun[8];
 };
 
+/*
+ * The Well Known LUNS (SAM-3) in our int representation of a LUN
+ */
+#define SCSI_W_LUN_BASE 0xc100
+#define SCSI_W_LUN_REPORT_LUNS (SCSI_W_LUN_BASE + 1)
+#define SCSI_W_LUN_ACCESS_CONTROL (SCSI_W_LUN_BASE + 2)
+#define SCSI_W_LUN_TARGET_LOG_PAGE (SCSI_W_LUN_BASE + 3)
+
+static inline int scsi_is_wlun(unsigned int lun)
+{
+       return (lun & 0xff00) == SCSI_W_LUN_BASE;
+}
+
+
 /*
  *  MESSAGE CODES
  */
index 13932abde15914e36a0d4f33e10b4a9a653f8c31..a0123d75ec9a7624f897bc2984ca4009b61abfbc 100644 (file)
@@ -2738,14 +2738,15 @@ void cgroup_fork_callbacks(struct task_struct *child)
  */
 void cgroup_mm_owner_callbacks(struct task_struct *old, struct task_struct *new)
 {
-       struct cgroup *oldcgrp, *newcgrp;
+       struct cgroup *oldcgrp, *newcgrp = NULL;
 
        if (need_mm_owner_callback) {
                int i;
                for (i = 0; i < CGROUP_SUBSYS_COUNT; i++) {
                        struct cgroup_subsys *ss = subsys[i];
                        oldcgrp = task_cgroup(old, ss->subsys_id);
-                       newcgrp = task_cgroup(new, ss->subsys_id);
+                       if (new)
+                               newcgrp = task_cgroup(new, ss->subsys_id);
                        if (oldcgrp == newcgrp)
                                continue;
                        if (ss->mm_owner_changed)
index f227bc1726906a52a803907299230f62b39edd84..827cd9adccb272f3d54a0ea8a98ba8c028cde211 100644 (file)
@@ -843,37 +843,25 @@ static void cpuset_change_cpumask(struct task_struct *tsk,
 /**
  * update_tasks_cpumask - Update the cpumasks of tasks in the cpuset.
  * @cs: the cpuset in which each task's cpus_allowed mask needs to be changed
+ * @heap: if NULL, defer allocating heap memory to cgroup_scan_tasks()
  *
  * Called with cgroup_mutex held
  *
  * The cgroup_scan_tasks() function will scan all the tasks in a cgroup,
  * calling callback functions for each.
  *
- * Return 0 if successful, -errno if not.
+ * No return value. It's guaranteed that cgroup_scan_tasks() always returns 0
+ * if @heap != NULL.
  */
-static int update_tasks_cpumask(struct cpuset *cs)
+static void update_tasks_cpumask(struct cpuset *cs, struct ptr_heap *heap)
 {
        struct cgroup_scanner scan;
-       struct ptr_heap heap;
-       int retval;
-
-       /*
-        * cgroup_scan_tasks() will initialize heap->gt for us.
-        * heap_init() is still needed here for we should not change
-        * cs->cpus_allowed when heap_init() fails.
-        */
-       retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL);
-       if (retval)
-               return retval;
 
        scan.cg = cs->css.cgroup;
        scan.test_task = cpuset_test_cpumask;
        scan.process_task = cpuset_change_cpumask;
-       scan.heap = &heap;
-       retval = cgroup_scan_tasks(&scan);
-
-       heap_free(&heap);
-       return retval;
+       scan.heap = heap;
+       cgroup_scan_tasks(&scan);
 }
 
 /**
@@ -883,6 +871,7 @@ static int update_tasks_cpumask(struct cpuset *cs)
  */
 static int update_cpumask(struct cpuset *cs, const char *buf)
 {
+       struct ptr_heap heap;
        struct cpuset trialcs;
        int retval;
        int is_load_balanced;
@@ -917,6 +906,10 @@ static int update_cpumask(struct cpuset *cs, const char *buf)
        if (cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed))
                return 0;
 
+       retval = heap_init(&heap, PAGE_SIZE, GFP_KERNEL, NULL);
+       if (retval)
+               return retval;
+
        is_load_balanced = is_sched_load_balance(&trialcs);
 
        mutex_lock(&callback_mutex);
@@ -927,9 +920,9 @@ static int update_cpumask(struct cpuset *cs, const char *buf)
         * Scan tasks in the cpuset, and update the cpumasks of any
         * that need an update.
         */
-       retval = update_tasks_cpumask(cs);
-       if (retval < 0)
-               return retval;
+       update_tasks_cpumask(cs, &heap);
+
+       heap_free(&heap);
 
        if (is_load_balanced)
                async_rebuild_sched_domains();
@@ -1965,7 +1958,7 @@ static void scan_for_empty_cpusets(const struct cpuset *root)
                     nodes_empty(cp->mems_allowed))
                        remove_tasks_in_empty_cpuset(cp);
                else {
-                       update_tasks_cpumask(cp);
+                       update_tasks_cpumask(cp, NULL);
                        update_tasks_nodemask(cp, &oldmems);
                }
        }
index 16395644a98ff8c060b2f5fd776fe7abadd61c6a..85a83c831856c193570e40a3b7d3e03ef8862d1c 100644 (file)
@@ -583,8 +583,6 @@ mm_need_new_owner(struct mm_struct *mm, struct task_struct *p)
         * If there are other users of the mm and the owner (us) is exiting
         * we need to find a new owner to take on the responsibility.
         */
-       if (!mm)
-               return 0;
        if (atomic_read(&mm->mm_users) <= 1)
                return 0;
        if (mm->owner != p)
@@ -627,6 +625,16 @@ retry:
        } while_each_thread(g, c);
 
        read_unlock(&tasklist_lock);
+       /*
+        * We found no owner yet mm_users > 1: this implies that we are
+        * most likely racing with swapoff (try_to_unuse()) or /proc or
+        * ptrace or page migration (get_task_mm()).  Mark owner as NULL,
+        * so that subsystems can understand the callback and take action.
+        */
+       down_write(&mm->mmap_sem);
+       cgroup_mm_owner_callbacks(mm->owner, NULL);
+       mm->owner = NULL;
+       up_write(&mm->mmap_sem);
        return;
 
 assign_new_owner:
index 59f3f0df35d4e04365480f5362aac097a236b63d..aef265325cd3596db981ed2515efec42f255804e 100644 (file)
@@ -753,8 +753,14 @@ static struct page *kimage_alloc_page(struct kimage *image,
                        *old = addr | (*old & ~PAGE_MASK);
 
                        /* The old page I have found cannot be a
-                        * destination page, so return it.
+                        * destination page, so return it if it's
+                        * gfp_flags honor the ones passed in.
                         */
+                       if (!(gfp_mask & __GFP_HIGHMEM) &&
+                           PageHighMem(old_page)) {
+                               kimage_free_pages(old_page);
+                               continue;
+                       }
                        addr = old_addr;
                        page = old_page;
                        break;
index eaa21fc9ad1d54250142a6c806115267865d3be6..25d955dbb989ce8c1c1ce75b156287ca1e800209 100644 (file)
@@ -488,7 +488,7 @@ static int write_mem_msg(int binary)
                if (err)
                        return err;
                if (CACHE_FLUSH_IS_SAFE)
-                       flush_icache_range(addr, addr + length + 1);
+                       flush_icache_range(addr, addr + length);
                return 0;
        }
 
@@ -1462,7 +1462,7 @@ acquirelock:
         * Get the passive CPU lock which will hold all the non-primary
         * CPU in a spin state while the debugger is active
         */
-       if (!kgdb_single_step || !kgdb_contthread) {
+       if (!kgdb_single_step) {
                for (i = 0; i < NR_CPUS; i++)
                        atomic_set(&passive_cpu_wait[i], 1);
        }
@@ -1475,7 +1475,7 @@ acquirelock:
 
 #ifdef CONFIG_SMP
        /* Signal the other CPUs to enter kgdb_wait() */
-       if ((!kgdb_single_step || !kgdb_contthread) && kgdb_do_roundup)
+       if ((!kgdb_single_step) && kgdb_do_roundup)
                kgdb_roundup_cpus(flags);
 #endif
 
@@ -1494,7 +1494,7 @@ acquirelock:
        kgdb_post_primary_code(ks->linux_regs, ks->ex_vector, ks->err_code);
        kgdb_deactivate_sw_breakpoints();
        kgdb_single_step = 0;
-       kgdb_contthread = NULL;
+       kgdb_contthread = current;
        exception_level = 0;
 
        /* Talk to debugger with gdbserial protocol */
@@ -1508,7 +1508,7 @@ acquirelock:
        kgdb_info[ks->cpu].task = NULL;
        atomic_set(&cpu_in_kgdb[ks->cpu], 0);
 
-       if (!kgdb_single_step || !kgdb_contthread) {
+       if (!kgdb_single_step) {
                for (i = NR_CPUS-1; i >= 0; i--)
                        atomic_set(&passive_cpu_wait[i], 0);
                /*
index cc1f81b50b82dddb19658dc4d10dd419087a59fc..13dd2db9fb2dc185a4a95a86aab9f89b4850ccaf 100644 (file)
@@ -1087,7 +1087,7 @@ hotplug_hrtick(struct notifier_block *nfb, unsigned long action, void *hcpu)
        return NOTIFY_DONE;
 }
 
-static void init_hrtick(void)
+static __init void init_hrtick(void)
 {
        hotcpu_notifier(hotplug_hrtick, 0);
 }
@@ -8909,6 +8909,9 @@ static int sched_rt_global_constraints(void)
        u64 rt_runtime, rt_period;
        int ret = 0;
 
+       if (sysctl_sched_rt_period <= 0)
+               return -EINVAL;
+
        rt_period = ktime_to_ns(tg->rt_bandwidth.rt_period);
        rt_runtime = tg->rt_bandwidth.rt_runtime;
 
@@ -8925,6 +8928,9 @@ static int sched_rt_global_constraints(void)
        unsigned long flags;
        int i;
 
+       if (sysctl_sched_rt_period <= 0)
+               return -EINVAL;
+
        spin_lock_irqsave(&def_rt_bandwidth.rt_runtime_lock, flags);
        for_each_possible_cpu(i) {
                struct rt_rq *rt_rq = &cpu_rq(i)->rt;
index 552310798dadf13e3b2059d5f84e050f7e0926e2..1113157b20581b07cbcdf325d4d3428cdd7cd288 100644 (file)
@@ -350,6 +350,7 @@ static void __enable_runtime(struct rq *rq)
                spin_lock(&rt_rq->rt_runtime_lock);
                rt_rq->rt_runtime = rt_b->rt_runtime;
                rt_rq->rt_time = 0;
+               rt_rq->rt_throttled = 0;
                spin_unlock(&rt_rq->rt_runtime_lock);
                spin_unlock(&rt_b->rt_runtime_lock);
        }
index 1876b526c7783db17d4dd5050a899e640670ef59..f8d968063cea38e348f63590ce73d409385cc5e9 100644 (file)
@@ -71,6 +71,16 @@ void clockevents_set_mode(struct clock_event_device *dev,
        }
 }
 
+/**
+ * clockevents_shutdown - shutdown the device and clear next_event
+ * @dev:       device to shutdown
+ */
+void clockevents_shutdown(struct clock_event_device *dev)
+{
+       clockevents_set_mode(dev, CLOCK_EVT_MODE_SHUTDOWN);
+       dev->next_event.tv64 = KTIME_MAX;
+}
+
 /**
  * clockevents_program_event - Reprogram the clock event device.
  * @expires:   absolute expiry time (monotonic clock)
@@ -206,7 +216,7 @@ void clockevents_exchange_device(struct clock_event_device *old,
 
        if (new) {
                BUG_ON(new->mode != CLOCK_EVT_MODE_UNUSED);
-               clockevents_set_mode(new, CLOCK_EVT_MODE_SHUTDOWN);
+               clockevents_shutdown(new);
        }
        local_irq_restore(flags);
 }
index 2f5a38294bf9ffc8639a5e623760c5242e96629b..bd7034542399f4badf620dbc5caf94578caf16ea 100644 (file)
@@ -235,9 +235,8 @@ static void tick_do_broadcast_on_off(void *why)
        case CLOCK_EVT_NOTIFY_BROADCAST_FORCE:
                if (!cpu_isset(cpu, tick_broadcast_mask)) {
                        cpu_set(cpu, tick_broadcast_mask);
-                       if (td->mode == TICKDEV_MODE_PERIODIC)
-                               clockevents_set_mode(dev,
-                                                    CLOCK_EVT_MODE_SHUTDOWN);
+                       if (bc->mode == TICKDEV_MODE_PERIODIC)
+                               clockevents_shutdown(dev);
                }
                if (*reason == CLOCK_EVT_NOTIFY_BROADCAST_FORCE)
                        tick_broadcast_force = 1;
@@ -246,7 +245,7 @@ static void tick_do_broadcast_on_off(void *why)
                if (!tick_broadcast_force &&
                    cpu_isset(cpu, tick_broadcast_mask)) {
                        cpu_clear(cpu, tick_broadcast_mask);
-                       if (td->mode == TICKDEV_MODE_PERIODIC)
+                       if (bc->mode == TICKDEV_MODE_PERIODIC)
                                tick_setup_periodic(dev, 0);
                }
                break;
@@ -254,7 +253,7 @@ static void tick_do_broadcast_on_off(void *why)
 
        if (cpus_empty(tick_broadcast_mask)) {
                if (!bc_stopped)
-                       clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+                       clockevents_shutdown(bc);
        } else if (bc_stopped) {
                if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC)
                        tick_broadcast_start_periodic(bc);
@@ -306,7 +305,7 @@ void tick_shutdown_broadcast(unsigned int *cpup)
 
        if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC) {
                if (bc && cpus_empty(tick_broadcast_mask))
-                       clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+                       clockevents_shutdown(bc);
        }
 
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
@@ -321,7 +320,7 @@ void tick_suspend_broadcast(void)
 
        bc = tick_broadcast_device.evtdev;
        if (bc)
-               clockevents_set_mode(bc, CLOCK_EVT_MODE_SHUTDOWN);
+               clockevents_shutdown(bc);
 
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
@@ -576,4 +575,12 @@ void tick_shutdown_broadcast_oneshot(unsigned int *cpup)
        spin_unlock_irqrestore(&tick_broadcast_lock, flags);
 }
 
+/*
+ * Check, whether the broadcast device is in one shot mode
+ */
+int tick_broadcast_oneshot_active(void)
+{
+       return tick_broadcast_device.mode == TICKDEV_MODE_ONESHOT;
+}
+
 #endif
index c4777193d56734d0276aa210ddbbad2e79c416c8..df12434b43ca09ec5ea9b0c48d679b842feddc9e 100644 (file)
@@ -33,7 +33,7 @@ DEFINE_PER_CPU(struct tick_device, tick_cpu_device);
  */
 ktime_t tick_next_period;
 ktime_t tick_period;
-int tick_do_timer_cpu __read_mostly = -1;
+int tick_do_timer_cpu __read_mostly = TICK_DO_TIMER_BOOT;
 DEFINE_SPINLOCK(tick_device_lock);
 
 /*
@@ -109,7 +109,8 @@ void tick_setup_periodic(struct clock_event_device *dev, int broadcast)
        if (!tick_device_is_functional(dev))
                return;
 
-       if (dev->features & CLOCK_EVT_FEAT_PERIODIC) {
+       if ((dev->features & CLOCK_EVT_FEAT_PERIODIC) &&
+           !tick_broadcast_oneshot_active()) {
                clockevents_set_mode(dev, CLOCK_EVT_MODE_PERIODIC);
        } else {
                unsigned long seq;
@@ -148,7 +149,7 @@ static void tick_setup_device(struct tick_device *td,
                 * If no cpu took the do_timer update, assign it to
                 * this cpu:
                 */
-               if (tick_do_timer_cpu == -1) {
+               if (tick_do_timer_cpu == TICK_DO_TIMER_BOOT) {
                        tick_do_timer_cpu = cpu;
                        tick_next_period = ktime_get();
                        tick_period = ktime_set(0, NSEC_PER_SEC / HZ);
@@ -249,7 +250,7 @@ static int tick_check_new_device(struct clock_event_device *newdev)
         * not give it back to the clockevents layer !
         */
        if (tick_is_broadcast_device(curdev)) {
-               clockevents_set_mode(curdev, CLOCK_EVT_MODE_SHUTDOWN);
+               clockevents_shutdown(curdev);
                curdev = NULL;
        }
        clockevents_exchange_device(curdev, newdev);
@@ -300,7 +301,8 @@ static void tick_shutdown(unsigned int *cpup)
        if (*cpup == tick_do_timer_cpu) {
                int cpu = first_cpu(cpu_online_map);
 
-               tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu : -1;
+               tick_do_timer_cpu = (cpu != NR_CPUS) ? cpu :
+                       TICK_DO_TIMER_NONE;
        }
        spin_unlock_irqrestore(&tick_device_lock, flags);
 }
@@ -311,7 +313,7 @@ static void tick_suspend(void)
        unsigned long flags;
 
        spin_lock_irqsave(&tick_device_lock, flags);
-       clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN);
+       clockevents_shutdown(td->evtdev);
        spin_unlock_irqrestore(&tick_device_lock, flags);
 }
 
index 0ffc2918ea6fb8365523ad0a63266cd68628b65f..469248782c2355c0c2d31cf731dc8c692023268e 100644 (file)
@@ -1,6 +1,10 @@
 /*
  * tick internal variable and functions used by low/high res code
  */
+
+#define TICK_DO_TIMER_NONE     -1
+#define TICK_DO_TIMER_BOOT     -2
+
 DECLARE_PER_CPU(struct tick_device, tick_cpu_device);
 extern spinlock_t tick_device_lock;
 extern ktime_t tick_next_period;
@@ -10,6 +14,8 @@ extern int tick_do_timer_cpu __read_mostly;
 extern void tick_setup_periodic(struct clock_event_device *dev, int broadcast);
 extern void tick_handle_periodic(struct clock_event_device *dev);
 
+extern void clockevents_shutdown(struct clock_event_device *dev);
+
 /*
  * NO_HZ / high resolution timer shared code
  */
@@ -29,6 +35,7 @@ extern void tick_broadcast_oneshot_control(unsigned long reason);
 extern void tick_broadcast_switch_to_oneshot(void);
 extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup);
 extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc);
+extern int tick_broadcast_oneshot_active(void);
 # else /* BROADCAST */
 static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 {
@@ -37,6 +44,7 @@ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc)
 static inline void tick_broadcast_oneshot_control(unsigned long reason) { }
 static inline void tick_broadcast_switch_to_oneshot(void) { }
 static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { }
+static inline int tick_broadcast_oneshot_active(void) { return 0; }
 # endif /* !BROADCAST */
 
 #else /* !ONESHOT */
@@ -66,6 +74,7 @@ static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc)
 {
        return 0;
 }
+static inline int tick_broadcast_oneshot_active(void) { return 0; }
 #endif /* !TICK_ONESHOT */
 
 /*
index 2e35501e61ddaa5b65a4275875931bc1fb438395..2e8de678e767a76d444c822307b7bd34baff67c5 100644 (file)
@@ -43,19 +43,17 @@ int tick_dev_program_event(struct clock_event_device *dev, ktime_t expires,
                 * and emit a warning.
                 */
                if (++i > 2) {
-                       printk(KERN_WARNING "CE: __tick_program_event of %s is "
-                              "stuck %llx %llx\n", dev->name ? dev->name : "?",
-                              now.tv64, expires.tv64);
-                       printk(KERN_WARNING
-                              "CE: increasing min_delta_ns %ld to %ld nsec\n",
-                              dev->min_delta_ns, dev->min_delta_ns << 1);
-                       WARN_ON(1);
-
-                       /* Double the min. delta and try again */
+                       /* Increase the min. delta and try again */
                        if (!dev->min_delta_ns)
                                dev->min_delta_ns = 5000;
                        else
-                               dev->min_delta_ns <<= 1;
+                               dev->min_delta_ns += dev->min_delta_ns >> 1;
+
+                       printk(KERN_WARNING
+                              "CE: %s increasing min_delta_ns to %lu nsec\n",
+                              dev->name ? dev->name : "?",
+                              dev->min_delta_ns << 1);
+
                        i = 0;
                }
 
index a87b0468568b026d90683bde0b2e9da0295c7caa..39019b3f76212939ef47903864511bd7e3b5430d 100644 (file)
@@ -75,6 +75,9 @@ static void tick_do_update_jiffies64(ktime_t now)
                                                           incr * ticks);
                }
                do_timer(++ticks);
+
+               /* Keep the tick_next_period variable up to date */
+               tick_next_period = ktime_add(last_jiffies_update, tick_period);
        }
        write_sequnlock(&xtime_lock);
 }
@@ -221,7 +224,7 @@ void tick_nohz_stop_sched_tick(int inidle)
         */
        if (unlikely(!cpu_online(cpu))) {
                if (cpu == tick_do_timer_cpu)
-                       tick_do_timer_cpu = -1;
+                       tick_do_timer_cpu = TICK_DO_TIMER_NONE;
        }
 
        if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
@@ -303,7 +306,7 @@ void tick_nohz_stop_sched_tick(int inidle)
                 * invoked.
                 */
                if (cpu == tick_do_timer_cpu)
-                       tick_do_timer_cpu = -1;
+                       tick_do_timer_cpu = TICK_DO_TIMER_NONE;
 
                ts->idle_sleeps++;
 
@@ -468,7 +471,7 @@ static void tick_nohz_handler(struct clock_event_device *dev)
         * this duty, then the jiffies update is still serialized by
         * xtime_lock.
         */
-       if (unlikely(tick_do_timer_cpu == -1))
+       if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
                tick_do_timer_cpu = cpu;
 
        /* Check, if the jiffies need an update */
@@ -570,7 +573,7 @@ static enum hrtimer_restart tick_sched_timer(struct hrtimer *timer)
         * this duty, then the jiffies update is still serialized by
         * xtime_lock.
         */
-       if (unlikely(tick_do_timer_cpu == -1))
+       if (unlikely(tick_do_timer_cpu == TICK_DO_TIMER_NONE))
                tick_do_timer_cpu = cpu;
 #endif
 
index 876ba6d5b6704921866d25cc47b899a045fbe6c3..8d2688ff1352e7ca9c20c6ac28292216fb8640ac 100644 (file)
@@ -422,9 +422,12 @@ static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
 {
        unsigned int offset = 0;
        struct sg_mapping_iter miter;
+       unsigned long flags;
 
        sg_miter_start(&miter, sgl, nents, SG_MITER_ATOMIC);
 
+       local_irq_save(flags);
+
        while (sg_miter_next(&miter) && offset < buflen) {
                unsigned int len;
 
@@ -442,6 +445,7 @@ static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
 
        sg_miter_stop(&miter);
 
+       local_irq_restore(flags);
        return offset;
 }
 
index 977edbdbc1debada5937958f5835b1dc88c9beba..8826fdf0f1801029e4b5e43555af44b5da203aae 100644 (file)
@@ -491,7 +491,7 @@ swiotlb_alloc_coherent(struct device *hwdev, size_t size,
                 * the lowest available address range.
                 */
                dma_addr_t handle;
-               handle = swiotlb_map_single(NULL, NULL, size, DMA_FROM_DEVICE);
+               handle = swiotlb_map_single(hwdev, NULL, size, DMA_FROM_DEVICE);
                if (swiotlb_dma_mapping_error(hwdev, handle))
                        return NULL;
 
index d8d1d1142248a511561b401a87b1590a5f94ba33..c399bc1093cbedb276f3e974353534560197e940 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <asm/page.h>          /* for PAGE_SIZE */
 #include <asm/div64.h>
+#include <asm/sections.h>      /* for dereference_function_descriptor() */
 
 /* Works only for digits and letters, but small and fast */
 #define TOLOWER(x) ((x) | 0x20)
@@ -513,16 +514,6 @@ static char *string(char *buf, char *end, char *s, int field_width, int precisio
        return buf;
 }
 
-static inline void *dereference_function_descriptor(void *ptr)
-{
-#if defined(CONFIG_IA64) || defined(CONFIG_PPC64)
-       void *p;
-       if (!probe_kernel_address(ptr, p))
-               ptr = p;
-#endif
-       return ptr;
-}
-
 static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int precision, int flags)
 {
        unsigned long value = (unsigned long) ptr;
index 0f1f7a7374bade23cf0052719a349a97322c5af4..36896f3eb7f5e5c2e4c3803cc8125fe461a71669 100644 (file)
@@ -250,6 +250,14 @@ static struct mem_cgroup *mem_cgroup_from_cont(struct cgroup *cont)
 
 struct mem_cgroup *mem_cgroup_from_task(struct task_struct *p)
 {
+       /*
+        * mm_update_next_owner() may clear mm->owner to NULL
+        * if it races with swapoff, page migration, etc.
+        * So this can be called with p == NULL.
+        */
+       if (unlikely(!p))
+               return NULL;
+
        return container_of(task_subsys_state(p, mem_cgroup_subsys_id),
                                struct mem_cgroup, css);
 }
@@ -549,6 +557,11 @@ static int mem_cgroup_charge_common(struct page *page, struct mm_struct *mm,
        if (likely(!memcg)) {
                rcu_read_lock();
                mem = mem_cgroup_from_task(rcu_dereference(mm->owner));
+               if (unlikely(!mem)) {
+                       rcu_read_unlock();
+                       kmem_cache_free(page_cgroup_cache, pc);
+                       return 0;
+               }
                /*
                 * For every charge from the cgroup, increment reference count
                 */
@@ -801,11 +814,16 @@ int mem_cgroup_shrink_usage(struct mm_struct *mm, gfp_t gfp_mask)
 
        rcu_read_lock();
        mem = mem_cgroup_from_task(rcu_dereference(mm->owner));
+       if (unlikely(!mem)) {
+               rcu_read_unlock();
+               return 0;
+       }
        css_get(&mem->css);
        rcu_read_unlock();
 
        do {
                progress = try_to_free_mem_cgroup_pages(mem, gfp_mask);
+               progress += res_counter_check_under_limit(&mem->res);
        } while (!progress && --retry);
 
        css_put(&mem->css);
index 486ed595ee6fa939f1cef55b7e4349d000d86317..16ce8b955dcff121623fc14810a9f12999f7ea3d 100644 (file)
@@ -69,6 +69,6 @@ struct zoneref *next_zones_zonelist(struct zoneref *z,
                                (z->zone && !zref_in_nodemask(z, nodes)))
                        z++;
 
-       *zone = zonelist_zone(z++);
+       *zone = zonelist_zone(z);
        return z;
 }
index fb486d5540f8bb0a7110245f2368fe2ace28338d..0c83e6afe7b223757f1608268436c59648c3633d 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1932,6 +1932,7 @@ init_kmem_cache_node(struct kmem_cache_node *n, struct kmem_cache *s)
        INIT_LIST_HEAD(&n->partial);
 #ifdef CONFIG_SLUB_DEBUG
        atomic_long_set(&n->nr_slabs, 0);
+       atomic_long_set(&n->total_objects, 0);
        INIT_LIST_HEAD(&n->full);
 #endif
 }
index ae532f50194319ce83b813a88b6a25aa5a4e85e5..d17cb6f6ab1029cdad5ef6a67523be159ff12211 100644 (file)
@@ -65,31 +65,25 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
        if (!dentry)
                goto put_memory;
 
-       error = -ENOSPC;
-       inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
-       if (!inode)
-               goto put_dentry;
-
-       d_instantiate(dentry, inode);
        error = -ENFILE;
-       file = alloc_file(shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
-                       &ramfs_file_operations);
+       file = get_empty_filp();
        if (!file)
                goto put_dentry;
 
-       inode->i_nlink = 0;     /* It is unlinked */
-
-       /* notify everyone as to the change of file size */
-       error = do_truncate(dentry, size, 0, file);
-       if (error < 0)
+       error = -ENOSPC;
+       inode = ramfs_get_inode(root->d_sb, S_IFREG | S_IRWXUGO, 0);
+       if (!inode)
                goto close_file;
 
+       d_instantiate(dentry, inode);
+       inode->i_size = size;
+       inode->i_nlink = 0;     /* It is unlinked */
+       init_file(file, shm_mnt, dentry, FMODE_WRITE | FMODE_READ,
+                       &ramfs_file_operations);
        return file;
 
 close_file:
        put_filp(file);
-       return ERR_PTR(error);
-
 put_dentry:
        dput(dentry);
 put_memory:
index 2ffe40cf2f01799634c478443284b80f62c9289c..10e320307ec015dad7e2a7db8b753f4a1886f645 100644 (file)
@@ -75,7 +75,6 @@ static int parse_opts(char *opts, struct p9_client *clnt)
        int option;
        int ret = 0;
 
-       clnt->trans_mod = v9fs_default_trans();
        clnt->dotu = 1;
        clnt->msize = 8192;
 
@@ -108,7 +107,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
                        clnt->msize = option;
                        break;
                case Opt_trans:
-                       clnt->trans_mod = v9fs_match_trans(&args[0]);
+                       clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
                        break;
                case Opt_legacy:
                        clnt->dotu = 0;
@@ -117,6 +116,10 @@ static int parse_opts(char *opts, struct p9_client *clnt)
                        continue;
                }
        }
+
+       if (!clnt->trans_mod)
+               clnt->trans_mod = v9fs_get_default_trans();
+
        kfree(options);
        return ret;
 }
@@ -150,6 +153,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
        if (!clnt)
                return ERR_PTR(-ENOMEM);
 
+       clnt->trans_mod = NULL;
        clnt->trans = NULL;
        spin_lock_init(&clnt->lock);
        INIT_LIST_HEAD(&clnt->fidlist);
@@ -235,6 +239,8 @@ void p9_client_destroy(struct p9_client *clnt)
                clnt->trans = NULL;
        }
 
+       v9fs_put_trans(clnt->trans_mod);
+
        list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
                p9_fid_destroy(fid);
 
index 44547201f5bcce723787cbeeee1c5a541a51ba3e..5ad3a3bd73b297725aed1c7998c0da80e9bdf2ae 100644 (file)
@@ -451,8 +451,10 @@ p9_put_data(struct cbuf *bufp, const char *data, int count,
                   unsigned char **pdata)
 {
        *pdata = buf_alloc(bufp, count);
+       if (*pdata == NULL)
+               return -ENOMEM;
        memmove(*pdata, data, count);
-       return count;
+       return 0;
 }
 
 static int
@@ -460,6 +462,8 @@ p9_put_user_data(struct cbuf *bufp, const char __user *data, int count,
                   unsigned char **pdata)
 {
        *pdata = buf_alloc(bufp, count);
+       if (*pdata == NULL)
+               return -ENOMEM;
        return copy_from_user(*pdata, data, count);
 }
 
index bdee1fb7cc62909a565717e7fd27a6c0903a1895..1084feb24cb0a3a9ef2409071c1ba3c4c06695aa 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/parser.h>
 #include <net/9p/transport.h>
 #include <linux/list.h>
+#include <linux/spinlock.h>
 
 #ifdef CONFIG_NET_9P_DEBUG
 unsigned int p9_debug_level = 0;       /* feature-rific global debug level  */
@@ -44,8 +45,8 @@ MODULE_PARM_DESC(debug, "9P debugging level");
  *
  */
 
+static DEFINE_SPINLOCK(v9fs_trans_lock);
 static LIST_HEAD(v9fs_trans_list);
-static struct p9_trans_module *v9fs_default_transport;
 
 /**
  * v9fs_register_trans - register a new transport with 9p
@@ -54,48 +55,87 @@ static struct p9_trans_module *v9fs_default_transport;
  */
 void v9fs_register_trans(struct p9_trans_module *m)
 {
+       spin_lock(&v9fs_trans_lock);
        list_add_tail(&m->list, &v9fs_trans_list);
-       if (m->def)
-               v9fs_default_transport = m;
+       spin_unlock(&v9fs_trans_lock);
 }
 EXPORT_SYMBOL(v9fs_register_trans);
 
 /**
- * v9fs_match_trans - match transport versus registered transports
+ * v9fs_unregister_trans - unregister a 9p transport
+ * @m: the transport to remove
+ *
+ */
+void v9fs_unregister_trans(struct p9_trans_module *m)
+{
+       spin_lock(&v9fs_trans_lock);
+       list_del_init(&m->list);
+       spin_unlock(&v9fs_trans_lock);
+}
+EXPORT_SYMBOL(v9fs_unregister_trans);
+
+/**
+ * v9fs_get_trans_by_name - get transport with the matching name
  * @name: string identifying transport
  *
  */
-struct p9_trans_module *v9fs_match_trans(const substring_t *name)
+struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name)
 {
-       struct list_head *p;
-       struct p9_trans_module *t = NULL;
-
-       list_for_each(p, &v9fs_trans_list) {
-               t = list_entry(p, struct p9_trans_module, list);
-               if (strncmp(t->name, name->from, name->to-name->from) == 0)
-                       return t;
-       }
-       return NULL;
+       struct p9_trans_module *t, *found = NULL;
+
+       spin_lock(&v9fs_trans_lock);
+
+       list_for_each_entry(t, &v9fs_trans_list, list)
+               if (strncmp(t->name, name->from, name->to-name->from) == 0 &&
+                   try_module_get(t->owner)) {
+                       found = t;
+                       break;
+               }
+
+       spin_unlock(&v9fs_trans_lock);
+       return found;
 }
-EXPORT_SYMBOL(v9fs_match_trans);
+EXPORT_SYMBOL(v9fs_get_trans_by_name);
 
 /**
- * v9fs_default_trans - returns pointer to default transport
+ * v9fs_get_default_trans - get the default transport
  *
  */
 
-struct p9_trans_module *v9fs_default_trans(void)
+struct p9_trans_module *v9fs_get_default_trans(void)
 {
-       if (v9fs_default_transport)
-               return v9fs_default_transport;
-       else if (!list_empty(&v9fs_trans_list))
-               return list_first_entry(&v9fs_trans_list,
-                                       struct p9_trans_module, list);
-       else
-               return NULL;
+       struct p9_trans_module *t, *found = NULL;
+
+       spin_lock(&v9fs_trans_lock);
+
+       list_for_each_entry(t, &v9fs_trans_list, list)
+               if (t->def && try_module_get(t->owner)) {
+                       found = t;
+                       break;
+               }
+
+       if (!found)
+               list_for_each_entry(t, &v9fs_trans_list, list)
+                       if (try_module_get(t->owner)) {
+                               found = t;
+                               break;
+                       }
+
+       spin_unlock(&v9fs_trans_lock);
+       return found;
 }
-EXPORT_SYMBOL(v9fs_default_trans);
+EXPORT_SYMBOL(v9fs_get_default_trans);
 
+/**
+ * v9fs_put_trans - put trans
+ * @m: transport to put
+ *
+ */
+void v9fs_put_trans(struct p9_trans_module *m)
+{
+       if (m)
+               module_put(m->owner);
+}
 
 /**
  * v9fs_init - Initialize module
@@ -120,6 +160,8 @@ static int __init init_p9(void)
 static void __exit exit_p9(void)
 {
        printk(KERN_INFO "Unloading 9P2000 support\n");
+
+       p9_trans_fd_exit();
 }
 
 module_init(init_p9)
index cdf137af7adc87d580280fbbce9b3c2d64b9dc82..d652baf5ff919c422664ed8890996d9f71beadc1 100644 (file)
@@ -151,7 +151,6 @@ struct p9_mux_poll_task {
  * @trans: reference to transport instance for this connection
  * @tagpool: id accounting for transactions
  * @err: error state
- * @equeue: event wait_q (?)
  * @req_list: accounting for requests which have been sent
  * @unsent_req_list: accounting for requests that haven't been sent
  * @rcall: current response &p9_fcall structure
@@ -178,7 +177,6 @@ struct p9_conn {
        struct p9_trans *trans;
        struct p9_idpool *tagpool;
        int err;
-       wait_queue_head_t equeue;
        struct list_head req_list;
        struct list_head unsent_req_list;
        struct p9_fcall *rcall;
@@ -240,22 +238,6 @@ static int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
 
 static void p9_conn_cancel(struct p9_conn *m, int err);
 
-static int p9_mux_global_init(void)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++)
-               p9_mux_poll_tasks[i].task = NULL;
-
-       p9_mux_wq = create_workqueue("v9fs");
-       if (!p9_mux_wq) {
-               printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
 static u16 p9_mux_get_tag(struct p9_conn *m)
 {
        int tag;
@@ -409,11 +391,11 @@ static void p9_mux_poll_stop(struct p9_conn *m)
 static struct p9_conn *p9_conn_create(struct p9_trans *trans)
 {
        int i, n;
-       struct p9_conn *m, *mtmp;
+       struct p9_conn *m;
 
        P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans,
                                                                trans->msize);
-       m = kmalloc(sizeof(struct p9_conn), GFP_KERNEL);
+       m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
        if (!m)
                return ERR_PTR(-ENOMEM);
 
@@ -424,25 +406,14 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
        m->trans = trans;
        m->tagpool = p9_idpool_create();
        if (IS_ERR(m->tagpool)) {
-               mtmp = ERR_PTR(-ENOMEM);
                kfree(m);
-               return mtmp;
+               return ERR_PTR(-ENOMEM);
        }
 
-       m->err = 0;
-       init_waitqueue_head(&m->equeue);
        INIT_LIST_HEAD(&m->req_list);
        INIT_LIST_HEAD(&m->unsent_req_list);
-       m->rcall = NULL;
-       m->rpos = 0;
-       m->rbuf = NULL;
-       m->wpos = m->wsize = 0;
-       m->wbuf = NULL;
        INIT_WORK(&m->rq, p9_read_work);
        INIT_WORK(&m->wq, p9_write_work);
-       m->wsched = 0;
-       memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
-       m->poll_task = NULL;
        n = p9_mux_poll_start(m);
        if (n) {
                kfree(m);
@@ -463,10 +434,8 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
        for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
                if (IS_ERR(m->poll_waddr[i])) {
                        p9_mux_poll_stop(m);
-                       mtmp = (void *)m->poll_waddr;   /* the error code */
                        kfree(m);
-                       m = mtmp;
-                       break;
+                       return (void *)m->poll_waddr;   /* the error code */
                }
        }
 
@@ -483,18 +452,13 @@ static void p9_conn_destroy(struct p9_conn *m)
 {
        P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
                m->mux_list.prev, m->mux_list.next);
-       p9_conn_cancel(m, -ECONNRESET);
-
-       if (!list_empty(&m->req_list)) {
-               /* wait until all processes waiting on this session exit */
-               P9_DPRINTK(P9_DEBUG_MUX,
-                       "mux %p waiting for empty request queue\n", m);
-               wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000);
-               P9_DPRINTK(P9_DEBUG_MUX, "mux %p request queue empty: %d\n", m,
-                       list_empty(&m->req_list));
-       }
 
        p9_mux_poll_stop(m);
+       cancel_work_sync(&m->rq);
+       cancel_work_sync(&m->wq);
+
+       p9_conn_cancel(m, -ECONNRESET);
+
        m->trans = NULL;
        p9_idpool_destroy(m->tagpool);
        kfree(m);
@@ -840,8 +804,6 @@ static void p9_read_work(struct work_struct *work)
                                        (*req->cb) (req, req->cba);
                                else
                                        kfree(req->rcall);
-
-                               wake_up(&m->equeue);
                        }
                } else {
                        if (err >= 0 && rcall->id != P9_RFLUSH)
@@ -908,8 +870,10 @@ static struct p9_req *p9_send_request(struct p9_conn *m,
        else
                n = p9_mux_get_tag(m);
 
-       if (n < 0)
+       if (n < 0) {
+               kfree(req);
                return ERR_PTR(-ENOMEM);
+       }
 
        p9_set_tag(tc, n);
 
@@ -984,8 +948,6 @@ static void p9_mux_flush_cb(struct p9_req *freq, void *a)
                        (*req->cb) (req, req->cba);
                else
                        kfree(req->rcall);
-
-               wake_up(&m->equeue);
        }
 
        kfree(freq->tcall);
@@ -1191,8 +1153,6 @@ void p9_conn_cancel(struct p9_conn *m, int err)
                else
                        kfree(req->rcall);
        }
-
-       wake_up(&m->equeue);
 }
 
 /**
@@ -1370,7 +1330,6 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
 {
        int ret, n;
        struct p9_trans_fd *ts = NULL;
-       mm_segment_t oldfs;
 
        if (trans && trans->status == Connected)
                ts = trans->priv;
@@ -1384,24 +1343,17 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
        if (!ts->wr->f_op || !ts->wr->f_op->poll)
                return -EIO;
 
-       oldfs = get_fs();
-       set_fs(get_ds());
-
        ret = ts->rd->f_op->poll(ts->rd, pt);
        if (ret < 0)
-               goto end;
+               return ret;
 
        if (ts->rd != ts->wr) {
                n = ts->wr->f_op->poll(ts->wr, pt);
-               if (n < 0) {
-                       ret = n;
-                       goto end;
-               }
+               if (n < 0)
+                       return n;
                ret = (ret & ~POLLOUT) | (n & ~POLLIN);
        }
 
-end:
-       set_fs(oldfs);
        return ret;
 }
 
@@ -1629,6 +1581,7 @@ static struct p9_trans_module p9_tcp_trans = {
        .maxsize = MAX_SOCK_BUF,
        .def = 1,
        .create = p9_trans_create_tcp,
+       .owner = THIS_MODULE,
 };
 
 static struct p9_trans_module p9_unix_trans = {
@@ -1636,6 +1589,7 @@ static struct p9_trans_module p9_unix_trans = {
        .maxsize = MAX_SOCK_BUF,
        .def = 0,
        .create = p9_trans_create_unix,
+       .owner = THIS_MODULE,
 };
 
 static struct p9_trans_module p9_fd_trans = {
@@ -1643,14 +1597,20 @@ static struct p9_trans_module p9_fd_trans = {
        .maxsize = MAX_SOCK_BUF,
        .def = 0,
        .create = p9_trans_create_fd,
+       .owner = THIS_MODULE,
 };
 
 int p9_trans_fd_init(void)
 {
-       int ret = p9_mux_global_init();
-       if (ret) {
-               printk(KERN_WARNING "9p: starting mux failed\n");
-               return ret;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++)
+               p9_mux_poll_tasks[i].task = NULL;
+
+       p9_mux_wq = create_workqueue("v9fs");
+       if (!p9_mux_wq) {
+               printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
+               return -ENOMEM;
        }
 
        v9fs_register_trans(&p9_tcp_trans);
@@ -1659,4 +1619,12 @@ int p9_trans_fd_init(void)
 
        return 0;
 }
-EXPORT_SYMBOL(p9_trans_fd_init);
+
+void p9_trans_fd_exit(void)
+{
+       v9fs_unregister_trans(&p9_tcp_trans);
+       v9fs_unregister_trans(&p9_unix_trans);
+       v9fs_unregister_trans(&p9_fd_trans);
+
+       destroy_workqueue(p9_mux_wq);
+}
index 42adc052b149251a46e3ac8a1bf039c91f00417f..94912e077a55e0ecdfdd137c9a9848256edd66b3 100644 (file)
@@ -528,6 +528,7 @@ static struct p9_trans_module p9_virtio_trans = {
        .create = p9_virtio_create,
        .maxsize = PAGE_SIZE*16,
        .def = 0,
+       .owner = THIS_MODULE,
 };
 
 /* The standard init function */
@@ -545,6 +546,7 @@ static int __init p9_virtio_init(void)
 static void __exit p9_virtio_cleanup(void)
 {
        unregister_virtio_driver(&p9_virtio_drv);
+       v9fs_unregister_trans(&p9_virtio_trans);
 }
 
 module_init(p9_virtio_init);
index d87de48ba6567b4a4bbafab249837b0a0d20cf66..9103a16a77be130fe603c696f187ef5b4b2f8297 100644 (file)
@@ -232,6 +232,7 @@ source "net/can/Kconfig"
 source "net/irda/Kconfig"
 source "net/bluetooth/Kconfig"
 source "net/rxrpc/Kconfig"
+source "net/phonet/Kconfig"
 
 config FIB_RULES
        bool
index 4f43e7f874f332afa1c8250c8cdfcea674f9671f..acaf819f24aad8f28c8f5ac8b5c36838bf927562 100644 (file)
@@ -42,6 +42,7 @@ obj-$(CONFIG_AF_RXRPC)                += rxrpc/
 obj-$(CONFIG_ATM)              += atm/
 obj-$(CONFIG_DECNET)           += decnet/
 obj-$(CONFIG_ECONET)           += econet/
+obj-$(CONFIG_PHONET)           += phonet/
 ifneq ($(CONFIG_VLAN_8021Q),)
 obj-y                          += 8021q/
 endif
index 5799fb52365ab45b8c90115c5b6ba7ef9ba49fe5..8f701cde5945b0f8ee7d9c6d6a3412130ce840a8 100644 (file)
@@ -1931,7 +1931,6 @@ static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
                switch (priv->lane_version) {
                case 1:
                        return priv->mcast_vcc;
-                       break;
                case 2: /* LANE2 wants arp for multicast addresses */
                        if (!compare_ether_addr(mac_to_find, bus_mac))
                                return priv->mcast_vcc;
index f5b21cb936996b87ec7138d8b8b81c3e1fa6f006..278a3ace14f664e019a85109ae6450e9ed13cff6 100644 (file)
@@ -164,6 +164,9 @@ static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *
 {
        int ret;
 
+       if (!test_bit(HCI_UP, &hdev->flags))
+               return -ENETDOWN;
+
        /* Serialize all requests */
        hci_req_lock(hdev);
        ret = __hci_request(hdev, req, opt, timeout);
index fdfc4b6a644816d1a69366494472126a903ee3d2..7091040e32ac53e255e99aa4d2c62b9a9056ca7f 100644 (file)
 #include <linux/if_arp.h>
 #include <linux/if_vlan.h>
 #include <linux/ip.h>
+#include <net/ip.h>
 #include <linux/ipv6.h>
 #include <linux/in.h>
 #include <linux/jhash.h>
@@ -890,7 +891,7 @@ int dev_alloc_name(struct net_device *dev, const char *name)
  *     Change name of a device, can pass format strings "eth%d".
  *     for wildcarding.
  */
-int dev_change_name(struct net_device *dev, char *newname)
+int dev_change_name(struct net_device *dev, const char *newname)
 {
        char oldname[IFNAMSIZ];
        int err = 0;
@@ -916,7 +917,6 @@ int dev_change_name(struct net_device *dev, char *newname)
                err = dev_alloc_name(dev, newname);
                if (err < 0)
                        return err;
-               strcpy(newname, dev->name);
        }
        else if (__dev_get_by_name(net, newname))
                return -EEXIST;
@@ -953,6 +953,38 @@ rollback:
        return err;
 }
 
+/**
+ *     dev_set_alias - change ifalias of a device
+ *     @dev: device
+ *     @alias: name up to IFALIASZ
+ *     @len: limit of bytes to copy from info
+ *
+ *     Set ifalias for a device,
+ */
+int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
+{
+       ASSERT_RTNL();
+
+       if (len >= IFALIASZ)
+               return -EINVAL;
+
+       if (!len) {
+               if (dev->ifalias) {
+                       kfree(dev->ifalias);
+                       dev->ifalias = NULL;
+               }
+               return 0;
+       }
+
+       dev->ifalias = krealloc(dev->ifalias, len+1, GFP_KERNEL);
+       if (!dev->ifalias)
+               return -ENOMEM;
+
+       strlcpy(dev->ifalias, alias, len+1);
+       return len;
+}
+
+
 /**
  *     netdev_features_change - device changes features
  *     @dev: device to cause notification
@@ -1667,7 +1699,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
 {
        u32 addr1, addr2, ports;
        u32 hash, ihl;
-       u8 ip_proto;
+       u8 ip_proto = 0;
 
        if (unlikely(!simple_tx_hashrnd_initialized)) {
                get_random_bytes(&simple_tx_hashrnd, 4);
@@ -1676,7 +1708,8 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
 
        switch (skb->protocol) {
        case htons(ETH_P_IP):
-               ip_proto = ip_hdr(skb)->protocol;
+               if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
+                       ip_proto = ip_hdr(skb)->protocol;
                addr1 = ip_hdr(skb)->saddr;
                addr2 = ip_hdr(skb)->daddr;
                ihl = ip_hdr(skb)->ihl;
@@ -3300,6 +3333,12 @@ static void dev_addr_discard(struct net_device *dev)
        netif_addr_unlock_bh(dev);
 }
 
+/**
+ *     dev_get_flags - get flags reported to userspace
+ *     @dev: device
+ *
+ *     Get the combination of flag bits exported through APIs to userspace.
+ */
 unsigned dev_get_flags(const struct net_device *dev)
 {
        unsigned flags;
@@ -3324,6 +3363,14 @@ unsigned dev_get_flags(const struct net_device *dev)
        return flags;
 }
 
+/**
+ *     dev_change_flags - change device settings
+ *     @dev: device
+ *     @flags: device state flags
+ *
+ *     Change settings on device based state flags. The flags are
+ *     in the userspace exported format.
+ */
 int dev_change_flags(struct net_device *dev, unsigned flags)
 {
        int ret, changes;
@@ -3393,6 +3440,13 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
        return ret;
 }
 
+/**
+ *     dev_set_mtu - Change maximum transfer unit
+ *     @dev: device
+ *     @new_mtu: new transfer unit
+ *
+ *     Change the maximum transfer size of the network device.
+ */
 int dev_set_mtu(struct net_device *dev, int new_mtu)
 {
        int err;
@@ -3417,6 +3471,13 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
        return err;
 }
 
+/**
+ *     dev_set_mac_address - Change Media Access Control Address
+ *     @dev: device
+ *     @sa: new address
+ *
+ *     Change the hardware (MAC) address of the device
+ */
 int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
 {
        int err;
@@ -4320,7 +4381,12 @@ void free_netdev(struct net_device *dev)
        put_device(&dev->dev);
 }
 
-/* Synchronize with packet receive processing. */
+/**
+ *     synchronize_net -  Synchronize with packet receive processing
+ *
+ *     Wait for packets currently being received to be done.
+ *     Does not block later packets from starting.
+ */
 void synchronize_net(void)
 {
        might_sleep();
@@ -4622,7 +4688,7 @@ netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
 }
 
 /**
- * netdev_dma_regiser - register the networking subsystem as a DMA client
+ * netdev_dma_register - register the networking subsystem as a DMA client
  */
 static int __init netdev_dma_register(void)
 {
@@ -4723,10 +4789,18 @@ err_name:
        return -ENOMEM;
 }
 
-char *netdev_drivername(struct net_device *dev, char *buffer, int len)
+/**
+ *     netdev_drivername - network driver for the device
+ *     @dev: network device
+ *     @buffer: buffer for resulting name
+ *     @len: size of buffer
+ *
+ *     Determine network driver for device.
+ */
+char *netdev_drivername(const struct net_device *dev, char *buffer, int len)
 {
-       struct device_driver *driver;
-       struct device *parent;
+       const struct device_driver *driver;
+       const struct device *parent;
 
        if (len <= 0 || !buffer)
                return buffer;
index 9d92e41826e7d02ef7d8836825ef27ebb8423f68..1dc728b38589699d4b85b215208bf6f0bde154f9 100644 (file)
@@ -927,8 +927,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
                        if (skb_queue_len(&neigh->arp_queue) >=
                            neigh->parms->queue_len) {
                                struct sk_buff *buff;
-                               buff = neigh->arp_queue.next;
-                               __skb_unlink(buff, &neigh->arp_queue);
+                               buff = __skb_dequeue(&neigh->arp_queue);
                                kfree_skb(buff);
                                NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);
                        }
@@ -1259,24 +1258,20 @@ static void neigh_proxy_process(unsigned long arg)
        struct neigh_table *tbl = (struct neigh_table *)arg;
        long sched_next = 0;
        unsigned long now = jiffies;
-       struct sk_buff *skb;
+       struct sk_buff *skb, *n;
 
        spin_lock(&tbl->proxy_queue.lock);
 
-       skb = tbl->proxy_queue.next;
-
-       while (skb != (struct sk_buff *)&tbl->proxy_queue) {
-               struct sk_buff *back = skb;
-               long tdif = NEIGH_CB(back)->sched_next - now;
+       skb_queue_walk_safe(&tbl->proxy_queue, skb, n) {
+               long tdif = NEIGH_CB(skb)->sched_next - now;
 
-               skb = skb->next;
                if (tdif <= 0) {
-                       struct net_device *dev = back->dev;
-                       __skb_unlink(back, &tbl->proxy_queue);
+                       struct net_device *dev = skb->dev;
+                       __skb_unlink(skb, &tbl->proxy_queue);
                        if (tbl->proxy_redo && netif_running(dev))
-                               tbl->proxy_redo(back);
+                               tbl->proxy_redo(skb);
                        else
-                               kfree_skb(back);
+                               kfree_skb(skb);
 
                        dev_put(dev);
                } else if (!sched_next || tdif < sched_next)
index c1f4e0d428c0bf75e79f8513e441262a6d28d949..92d6b946731430ddb9b5533498bc6e04c104c3c0 100644 (file)
@@ -209,9 +209,44 @@ static ssize_t store_tx_queue_len(struct device *dev,
        return netdev_store(dev, attr, buf, len, change_tx_queue_len);
 }
 
+static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr,
+                            const char *buf, size_t len)
+{
+       struct net_device *netdev = to_net_dev(dev);
+       size_t count = len;
+       ssize_t ret;
+
+       if (!capable(CAP_NET_ADMIN))
+               return -EPERM;
+
+       /* ignore trailing newline */
+       if (len >  0 && buf[len - 1] == '\n')
+               --count;
+
+       rtnl_lock();
+       ret = dev_set_alias(netdev, buf, count);
+       rtnl_unlock();
+
+       return ret < 0 ? ret : len;
+}
+
+static ssize_t show_ifalias(struct device *dev,
+                           struct device_attribute *attr, char *buf)
+{
+       const struct net_device *netdev = to_net_dev(dev);
+       ssize_t ret = 0;
+
+       rtnl_lock();
+       if (netdev->ifalias)
+               ret = sprintf(buf, "%s\n", netdev->ifalias);
+       rtnl_unlock();
+       return ret;
+}
+
 static struct device_attribute net_class_attributes[] = {
        __ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
        __ATTR(dev_id, S_IRUGO, show_dev_id, NULL),
+       __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias),
        __ATTR(iflink, S_IRUGO, show_iflink, NULL),
        __ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
        __ATTR(features, S_IRUGO, show_features, NULL),
@@ -418,6 +453,7 @@ static void netdev_release(struct device *d)
 
        BUG_ON(dev->reg_state != NETREG_RELEASED);
 
+       kfree(dev->ifalias);
        kfree((char *)dev - dev->padded);
 }
 
index 71edb8b36341622df50ec48f32127b1be490b19f..8862498fd4a6142673b45f896e5b5933c94832f2 100644 (file)
@@ -586,6 +586,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
 {
        return NLMSG_ALIGN(sizeof(struct ifinfomsg))
               + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
+              + nla_total_size(IFALIASZ) /* IFLA_IFALIAS */
               + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */
               + nla_total_size(sizeof(struct rtnl_link_ifmap))
               + nla_total_size(sizeof(struct rtnl_link_stats))
@@ -640,6 +641,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
        if (txq->qdisc_sleeping)
                NLA_PUT_STRING(skb, IFLA_QDISC, txq->qdisc_sleeping->ops->id);
 
+       if (dev->ifalias)
+               NLA_PUT_STRING(skb, IFLA_IFALIAS, dev->ifalias);
+
        if (1) {
                struct rtnl_link_ifmap map = {
                        .mem_start   = dev->mem_start,
@@ -713,6 +717,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_LINKMODE]         = { .type = NLA_U8 },
        [IFLA_LINKINFO]         = { .type = NLA_NESTED },
        [IFLA_NET_NS_PID]       = { .type = NLA_U32 },
+       [IFLA_IFALIAS]          = { .type = NLA_STRING, .len = IFALIASZ-1 },
 };
 
 static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
@@ -853,6 +858,14 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
                modified = 1;
        }
 
+       if (tb[IFLA_IFALIAS]) {
+               err = dev_set_alias(dev, nla_data(tb[IFLA_IFALIAS]),
+                                   nla_len(tb[IFLA_IFALIAS]));
+               if (err < 0)
+                       goto errout;
+               modified = 1;
+       }
+
        if (tb[IFLA_BROADCAST]) {
                nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
                send_addr_notify = 1;
index ca1ccdf1ef7612b87d16f53f803b2460de612360..8bd248a64879bcac5f91a53659abcb281ada594a 100644 (file)
@@ -363,8 +363,7 @@ static void kfree_skbmem(struct sk_buff *skb)
        }
 }
 
-/* Free everything but the sk_buff shell. */
-static void skb_release_all(struct sk_buff *skb)
+static void skb_release_head_state(struct sk_buff *skb)
 {
        dst_release(skb->dst);
 #ifdef CONFIG_XFRM
@@ -388,6 +387,12 @@ static void skb_release_all(struct sk_buff *skb)
        skb->tc_verd = 0;
 #endif
 #endif
+}
+
+/* Free everything but the sk_buff shell. */
+static void skb_release_all(struct sk_buff *skb)
+{
+       skb_release_head_state(skb);
        skb_release_data(skb);
 }
 
@@ -424,6 +429,38 @@ void kfree_skb(struct sk_buff *skb)
        __kfree_skb(skb);
 }
 
+int skb_recycle_check(struct sk_buff *skb, int skb_size)
+{
+       struct skb_shared_info *shinfo;
+
+       if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
+               return 0;
+
+       skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD);
+       if (skb_end_pointer(skb) - skb->head < skb_size)
+               return 0;
+
+       if (skb_shared(skb) || skb_cloned(skb))
+               return 0;
+
+       skb_release_head_state(skb);
+       shinfo = skb_shinfo(skb);
+       atomic_set(&shinfo->dataref, 1);
+       shinfo->nr_frags = 0;
+       shinfo->gso_size = 0;
+       shinfo->gso_segs = 0;
+       shinfo->gso_type = 0;
+       shinfo->ip6_frag_id = 0;
+       shinfo->frag_list = NULL;
+
+       memset(skb, 0, offsetof(struct sk_buff, tail));
+       skb_reset_tail_pointer(skb);
+       skb->data = skb->head + NET_SKB_PAD;
+
+       return 1;
+}
+EXPORT_SYMBOL(skb_recycle_check);
+
 static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 {
        new->tstamp             = old->tstamp;
@@ -701,6 +738,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
 #endif
        long off;
 
+       BUG_ON(nhead < 0);
+
        if (skb_shared(skb))
                BUG();
 
index 23b8b9da36b322451ef4ffdeeb39571c8fff039a..2d358dd8a03e6acc47bc0797d9486d04ed945976 100644 (file)
@@ -154,7 +154,8 @@ static const char *af_family_key_strings[AF_MAX+1] = {
   "sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE"  , "sk_lock-AF_LLC"      ,
   "sk_lock-27"       , "sk_lock-28"          , "sk_lock-AF_CAN"      ,
   "sk_lock-AF_TIPC"  , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV"        ,
-  "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_MAX"
+  "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_PHONET"   ,
+  "sk_lock-AF_MAX"
 };
 static const char *af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_UNSPEC", "slock-AF_UNIX"     , "slock-AF_INET"     ,
@@ -168,7 +169,8 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = {
   "slock-AF_PPPOX" , "slock-AF_WANPIPE"  , "slock-AF_LLC"      ,
   "slock-27"       , "slock-28"          , "slock-AF_CAN"      ,
   "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
-  "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_MAX"
+  "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_PHONET"   ,
+  "slock-AF_MAX"
 };
 static const char *af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_UNSPEC", "clock-AF_UNIX"     , "clock-AF_INET"     ,
@@ -182,7 +184,8 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = {
   "clock-AF_PPPOX" , "clock-AF_WANPIPE"  , "clock-AF_LLC"      ,
   "clock-27"       , "clock-28"          , "clock-AF_CAN"      ,
   "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
-  "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_MAX"
+  "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_PHONET"   ,
+  "clock-AF_MAX"
 };
 #endif
 
index 8a3ac1fa71a976e8c8f4c4f2dfd9fa87af2f9a99..1fbff5fa424101fb463905be71d1cc06299fa74c 100644 (file)
@@ -469,7 +469,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
         */
        err = -EADDRNOTAVAIL;
        if (!sysctl_ip_nonlocal_bind &&
-           !inet->freebind &&
+           !(inet->freebind || inet->transparent) &&
            addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
            chk_addr_ret != RTN_LOCAL &&
            chk_addr_ret != RTN_MULTICAST &&
index 0c1ae68ee84bb24a08b73d6798ceb66db63bd176..21fcc5a9045ff570014d5eb9a366569d48ca1bd8 100644 (file)
@@ -335,6 +335,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
                                        .saddr = ireq->loc_addr,
                                        .tos = RT_CONN_FLAGS(sk) } },
                            .proto = sk->sk_protocol,
+                           .flags = inet_sk_flowi_flags(sk),
                            .uli_u = { .ports =
                                       { .sport = inet_sk(sk)->sport,
                                         .dport = ireq->rmt_port } } };
@@ -515,6 +516,8 @@ struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req,
                newicsk->icsk_bind_hash = NULL;
 
                inet_sk(newsk)->dport = inet_rsk(req)->rmt_port;
+               inet_sk(newsk)->num = ntohs(inet_rsk(req)->loc_port);
+               inet_sk(newsk)->sport = inet_rsk(req)->loc_port;
                newsk->sk_write_space = sk_stream_write_space;
 
                newicsk->icsk_retransmits = 0;
index 743f011b9a84189bd9284721e4a1ac2a704e68b8..1c5fd38f8824a9a58cafc9220773b134c4a4b771 100644 (file)
@@ -126,6 +126,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
                tw->tw_reuse        = sk->sk_reuse;
                tw->tw_hash         = sk->sk_hash;
                tw->tw_ipv6only     = 0;
+               tw->tw_transparent  = inet->transparent;
                tw->tw_prot         = sk->sk_prot_creator;
                twsk_net_set(tw, hold_net(sock_net(sk)));
                atomic_set(&tw->tw_refcnt, 1);
index d533a89e08de14d2e7417b41dddcb99d8e9c881b..d2a8f8bb78a677e5be6b9e39a4f2fe7c3b181a27 100644 (file)
@@ -340,6 +340,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
                                                        .saddr = inet->saddr,
                                                        .tos = RT_CONN_FLAGS(sk) } },
                                            .proto = sk->sk_protocol,
+                                           .flags = inet_sk_flowi_flags(sk),
                                            .uli_u = { .ports =
                                                       { .sport = inet->sport,
                                                         .dport = inet->dport } } };
@@ -1371,7 +1372,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
                                    .uli_u = { .ports =
                                               { .sport = tcp_hdr(skb)->dest,
                                                 .dport = tcp_hdr(skb)->source } },
-                                   .proto = sk->sk_protocol };
+                                   .proto = sk->sk_protocol,
+                                   .flags = ip_reply_arg_flowi_flags(arg) };
                security_skb_classify_flow(skb, &fl);
                if (ip_route_output_key(sock_net(sk), &rt, &fl))
                        return;
index 105d92a039b931c0bc485503cc913057eb3b96e1..465abf0a9869c768ab7b7f0832050a2a0812f05c 100644 (file)
@@ -419,7 +419,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                             (1<<IP_TTL) | (1<<IP_HDRINCL) |
                             (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
                             (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
-                            (1<<IP_PASSSEC))) ||
+                            (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
            optname == IP_MULTICAST_TTL ||
            optname == IP_MULTICAST_LOOP) {
                if (optlen >= sizeof(int)) {
@@ -878,6 +878,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                err = xfrm_user_policy(sk, optname, optval, optlen);
                break;
 
+       case IP_TRANSPARENT:
+               if (!capable(CAP_NET_ADMIN)) {
+                       err = -EPERM;
+                       break;
+               }
+               if (optlen < 1)
+                       goto e_inval;
+               inet->transparent = !!val;
+               break;
+
        default:
                err = -ENOPROTOOPT;
                break;
@@ -1130,6 +1140,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        case IP_FREEBIND:
                val = inet->freebind;
                break;
+       case IP_TRANSPARENT:
+               val = inet->transparent;
+               break;
        default:
                release_sock(sk);
                return -ENOPROTOOPT;
index f8edacdf991df1d74fac5e0bafad89c9caa481ce..01671ad51ed34d784bcec2f8d620b2283a8941dc 100644 (file)
@@ -20,6 +20,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
        unsigned int type;
 
        type = inet_addr_type(&init_net, iph->saddr);
+       if (skb->sk && inet_sk(skb->sk)->transparent)
+               type = RTN_LOCAL;
        if (addr_type == RTN_UNSPEC)
                addr_type = type;
 
@@ -33,6 +35,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
                fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
                fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
                fl.mark = skb->mark;
+               fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
                if (ip_route_output_key(&init_net, &rt, &fl) != 0)
                        return -1;
 
index 11976ea2988493eee1b108aceb677da3d5637250..112dcfa12900709e28cbe94591528932fda04c7e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/udp.h>
 #include <net/checksum.h>
 #include <net/tcp.h>
+#include <net/route.h>
 
 #include <linux/netfilter_ipv4.h>
 #include <net/netfilter/nf_conntrack.h>
index f62187bb6d087caa3b0680e2122cd39988a77fb6..a6d7c584f53b9a4f7493ac3b73b2e4b2602f66bf 100644 (file)
@@ -2361,11 +2361,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
                    ipv4_is_zeronet(oldflp->fl4_src))
                        goto out;
 
-               /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
-               dev_out = ip_dev_find(net, oldflp->fl4_src);
-               if (dev_out == NULL)
-                       goto out;
-
                /* I removed check for oif == dev_out->oif here.
                   It was wrong for two reasons:
                   1. ip_dev_find(net, saddr) can return wrong iface, if saddr
@@ -2377,6 +2372,11 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
                if (oldflp->oif == 0
                    && (ipv4_is_multicast(oldflp->fl4_dst) ||
                        oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
+                       /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
+                       dev_out = ip_dev_find(net, oldflp->fl4_src);
+                       if (dev_out == NULL)
+                               goto out;
+
                        /* Special hack: user can direct multicasts
                           and limited broadcast via necessary interface
                           without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
@@ -2395,9 +2395,15 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
                        fl.oif = dev_out->ifindex;
                        goto make_route;
                }
-               if (dev_out)
+
+               if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) {
+                       /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
+                       dev_out = ip_dev_find(net, oldflp->fl4_src);
+                       if (dev_out == NULL)
+                               goto out;
                        dev_put(dev_out);
-               dev_out = NULL;
+                       dev_out = NULL;
+               }
        }
 
 
index 9d38005abbace6956bf3a5493aaacf58d7a9d90b..d346c22aa6ae170a45d540f27cc04c3028f16c6e 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/cryptohash.h>
 #include <linux/kernel.h>
 #include <net/tcp.h>
+#include <net/route.h>
 
 /* Timestamps: lowest 9 bits store TCP options */
 #define TSBITS 9
@@ -296,6 +297,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
        treq->rcv_isn           = ntohl(th->seq) - 1;
        treq->snt_isn           = cookie;
        req->mss                = mss;
+       ireq->loc_port          = th->dest;
        ireq->rmt_port          = th->source;
        ireq->loc_addr          = ip_hdr(skb)->daddr;
        ireq->rmt_addr          = ip_hdr(skb)->saddr;
@@ -337,6 +339,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
                                                .saddr = ireq->loc_addr,
                                                .tos = RT_CONN_FLAGS(sk) } },
                                    .proto = IPPROTO_TCP,
+                                   .flags = inet_sk_flowi_flags(sk),
                                    .uli_u = { .ports =
                                               { .sport = th->dest,
                                                 .dport = th->source } } };
index 1ab341e5d3e0f70383fdfa460b0ee9071b282df7..7d81a1ee5507c08a2fb2b297fb387a7cf6bc55bb 100644 (file)
@@ -384,13 +384,17 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
 
        /* Connected? */
        if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) {
+               int target = sock_rcvlowat(sk, 0, INT_MAX);
+
+               if (tp->urg_seq == tp->copied_seq &&
+                   !sock_flag(sk, SOCK_URGINLINE) &&
+                   tp->urg_data)
+                       target--;
+
                /* Potential race condition. If read of tp below will
                 * escape above sk->sk_state, we can be illegally awaken
                 * in SYN_* states. */
-               if ((tp->rcv_nxt != tp->copied_seq) &&
-                   (tp->urg_seq != tp->copied_seq ||
-                    tp->rcv_nxt != tp->copied_seq + 1 ||
-                    sock_flag(sk, SOCK_URGINLINE) || !tp->urg_data))
+               if (tp->rcv_nxt - tp->copied_seq >= target)
                        mask |= POLLIN | POLLRDNORM;
 
                if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
index 85627f83665fa23b40aca36c600c827b3f462dc5..3b76bce769dd4dd29f48e7278c90f64cd47a65a5 100644 (file)
@@ -1746,6 +1746,8 @@ int tcp_use_frto(struct sock *sk)
                return 0;
 
        skb = tcp_write_queue_head(sk);
+       if (tcp_skb_is_last(sk, skb))
+               return 1;
        skb = tcp_write_queue_next(sk, skb);    /* Skips head */
        tcp_for_write_queue_from(skb, sk) {
                if (skb == tcp_send_head(sk))
@@ -4156,7 +4158,7 @@ drop:
                                skb1 = skb1->prev;
                        }
                }
-               __skb_insert(skb, skb1, skb1->next, &tp->out_of_order_queue);
+               __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
 
                /* And clean segments covered by new one as whole. */
                while ((skb1 = skb->next) !=
@@ -4254,7 +4256,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
                memcpy(nskb->head, skb->head, header);
                memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
                TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
-               __skb_insert(nskb, skb->prev, skb, list);
+               __skb_queue_before(list, skb, nskb);
                skb_set_owner_r(nskb, sk);
 
                /* Copy data, releasing collapsed skbs. */
index 44aef1c1f37332b3583fbf05352afe7688faeca1..8b24bd833cb446fb84b927d38a0c815ebb0f6f50 100644 (file)
@@ -591,6 +591,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
                                      ip_hdr(skb)->saddr, /* XXX */
                                      sizeof(struct tcphdr), IPPROTO_TCP, 0);
        arg.csumoffset = offsetof(struct tcphdr, check) / 2;
+       arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
 
        net = dev_net(skb->dst->dev);
        ip_send_reply(net->ipv4.tcp_sock, skb,
@@ -606,7 +607,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
 
 static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
                            u32 win, u32 ts, int oif,
-                           struct tcp_md5sig_key *key)
+                           struct tcp_md5sig_key *key,
+                           int reply_flags)
 {
        struct tcphdr *th = tcp_hdr(skb);
        struct {
@@ -618,7 +620,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
                        ];
        } rep;
        struct ip_reply_arg arg;
-       struct net *net = dev_net(skb->dev);
+       struct net *net = dev_net(skb->dst->dev);
 
        memset(&rep.th, 0, sizeof(struct tcphdr));
        memset(&arg, 0, sizeof(arg));
@@ -659,6 +661,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
                                    ip_hdr(skb)->daddr, &rep.th);
        }
 #endif
+       arg.flags = reply_flags;
        arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
                                      ip_hdr(skb)->saddr, /* XXX */
                                      arg.iov[0].iov_len, IPPROTO_TCP, 0);
@@ -681,7 +684,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
                        tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
                        tcptw->tw_ts_recent,
                        tw->tw_bound_dev_if,
-                       tcp_twsk_md5_key(tcptw)
+                       tcp_twsk_md5_key(tcptw),
+                       tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0
                        );
 
        inet_twsk_put(tw);
@@ -694,7 +698,8 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
                        tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
                        req->ts_recent,
                        0,
-                       tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr));
+                       tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr),
+                       inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0);
 }
 
 /*
@@ -1244,6 +1249,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        ireq = inet_rsk(req);
        ireq->loc_addr = daddr;
        ireq->rmt_addr = saddr;
+       ireq->no_srccheck = inet_sk(sk)->transparent;
        ireq->opt = tcp_v4_save_options(sk, skb);
        if (!want_cookie)
                TCP_ECN_create_request(req, tcp_hdr(skb));
index c3d58ee3e16ff39867094744a93e5a2338e5b507..493553c71d3249ba9ad98408ea754a5e13f2b59d 100644 (file)
@@ -1932,8 +1932,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
        /* Collapse two adjacent packets if worthwhile and we can. */
        if (!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) &&
            (skb->len < (cur_mss >> 1)) &&
-           (tcp_write_queue_next(sk, skb) != tcp_send_head(sk)) &&
            (!tcp_skb_is_last(sk, skb)) &&
+           (tcp_write_queue_next(sk, skb) != tcp_send_head(sk)) &&
            (skb_shinfo(skb)->nr_frags == 0 &&
             skb_shinfo(tcp_write_queue_next(sk, skb))->nr_frags == 0) &&
            (tcp_skb_pcount(skb) == 1 &&
@@ -2275,7 +2275,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        th->syn = 1;
        th->ack = 1;
        TCP_ECN_make_synack(req, th);
-       th->source = inet_sk(sk)->sport;
+       th->source = ireq->loc_port;
        th->dest = ireq->rmt_port;
        /* Setting of flags are superfluous here for callers (and ECE is
         * not even correctly set)
index 8e42fbbd57616316df2692a39379398f9486ac22..c83d0ef469c9db4bd31a18a60c1f89e44fb0c519 100644 (file)
@@ -302,6 +302,13 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
        return result;
 }
 
+struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
+                            __be32 daddr, __be16 dport, int dif)
+{
+       return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
+}
+EXPORT_SYMBOL_GPL(udp4_lib_lookup);
+
 static inline struct sock *udp_v4_mcast_next(struct sock *sk,
                                             __be16 loc_port, __be32 loc_addr,
                                             __be16 rmt_port, __be32 rmt_addr,
@@ -951,6 +958,27 @@ int udp_disconnect(struct sock *sk, int flags)
        return 0;
 }
 
+static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+       int is_udplite = IS_UDPLITE(sk);
+       int rc;
+
+       if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
+               /* Note that an ENOMEM error is charged twice */
+               if (rc == -ENOMEM)
+                       UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS,
+                                        is_udplite);
+               goto drop;
+       }
+
+       return 0;
+
+drop:
+       UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
+       kfree_skb(skb);
+       return -1;
+}
+
 /* returns:
  *  -1: error
  *   0: success
@@ -989,9 +1017,7 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
                    up->encap_rcv != NULL) {
                        int ret;
 
-                       bh_unlock_sock(sk);
                        ret = (*up->encap_rcv)(sk, skb);
-                       bh_lock_sock(sk);
                        if (ret <= 0) {
                                UDP_INC_STATS_BH(sock_net(sk),
                                                 UDP_MIB_INDATAGRAMS,
@@ -1044,17 +1070,16 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
                        goto drop;
        }
 
-       if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
-               /* Note that an ENOMEM error is charged twice */
-               if (rc == -ENOMEM) {
-                       UDP_INC_STATS_BH(sock_net(sk),
-                                       UDP_MIB_RCVBUFERRORS, is_udplite);
-                       atomic_inc(&sk->sk_drops);
-               }
-               goto drop;
-       }
+       rc = 0;
 
-       return 0;
+       bh_lock_sock(sk);
+       if (!sock_owned_by_user(sk))
+               rc = __udp_queue_rcv_skb(sk, skb);
+       else
+               sk_add_backlog(sk, skb);
+       bh_unlock_sock(sk);
+
+       return rc;
 
 drop:
        UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
@@ -1092,15 +1117,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
                                skb1 = skb_clone(skb, GFP_ATOMIC);
 
                        if (skb1) {
-                               int ret = 0;
-
-                               bh_lock_sock(sk);
-                               if (!sock_owned_by_user(sk))
-                                       ret = udp_queue_rcv_skb(sk, skb1);
-                               else
-                                       sk_add_backlog(sk, skb1);
-                               bh_unlock_sock(sk);
-
+                               int ret = udp_queue_rcv_skb(sk, skb1);
                                if (ret > 0)
                                        /* we should probably re-process instead
                                         * of dropping packets here. */
@@ -1195,13 +1212,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
                        uh->dest, inet_iif(skb), udptable);
 
        if (sk != NULL) {
-               int ret = 0;
-               bh_lock_sock(sk);
-               if (!sock_owned_by_user(sk))
-                       ret = udp_queue_rcv_skb(sk, skb);
-               else
-                       sk_add_backlog(sk, skb);
-               bh_unlock_sock(sk);
+               int ret = udp_queue_rcv_skb(sk, skb);
                sock_put(sk);
 
                /* a return value > 0 means to resubmit the input, but
@@ -1494,7 +1505,7 @@ struct proto udp_prot = {
        .sendmsg           = udp_sendmsg,
        .recvmsg           = udp_recvmsg,
        .sendpage          = udp_sendpage,
-       .backlog_rcv       = udp_queue_rcv_skb,
+       .backlog_rcv       = __udp_queue_rcv_skb,
        .hash              = udp_lib_hash,
        .unhash            = udp_lib_unhash,
        .get_port          = udp_v4_get_port,
index 95055f8c3f35eb18d17f4848fe0ae72ed648bbc2..f018704ecb8698516932ca57a4151dafa6152f3f 100644 (file)
@@ -50,6 +50,7 @@
 #include <net/ipip.h>
 #include <net/protocol.h>
 #include <net/inet_common.h>
+#include <net/route.h>
 #include <net/transp_v6.h>
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
index 62e39ace05888f72fcda1e3b54b3bcc2d366f005..26654b26d7fafd3f2d20103484498b2098d30461 100644 (file)
@@ -97,8 +97,6 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
        hdrlen -= 2;
        if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
                return ret;
-       } else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
-               pr_debug("Not strict - not implemented");
        } else {
                pr_debug("Strict ");
                pr_debug("#%d ", optinfo->optsnr);
@@ -177,6 +175,12 @@ hbh_mt6_check(const char *tablename, const void *entry,
                pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
                return false;
        }
+
+       if (optsinfo->flags & IP6T_OPTS_NSTRICT) {
+               pr_debug("ip6t_opts: Not strict - not implemented");
+               return false;
+       }
+
        return true;
 }
 
index 52d06dd4b8176f01a4e0b796e38d1fedf5c8c7c8..9967ac7a01a87f49323b7e5f0d4ed9ff1ff283b6 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/ipv6.h>
 #include <linux/icmpv6.h>
 #include <linux/random.h>
-#include <linux/jhash.h>
 
 #include <net/sock.h>
 #include <net/snmp.h>
@@ -103,39 +102,12 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
 };
 #endif
 
-static unsigned int ip6qhashfn(__be32 id, const struct in6_addr *saddr,
-                              const struct in6_addr *daddr)
-{
-       u32 a, b, c;
-
-       a = (__force u32)saddr->s6_addr32[0];
-       b = (__force u32)saddr->s6_addr32[1];
-       c = (__force u32)saddr->s6_addr32[2];
-
-       a += JHASH_GOLDEN_RATIO;
-       b += JHASH_GOLDEN_RATIO;
-       c += nf_frags.rnd;
-       __jhash_mix(a, b, c);
-
-       a += (__force u32)saddr->s6_addr32[3];
-       b += (__force u32)daddr->s6_addr32[0];
-       c += (__force u32)daddr->s6_addr32[1];
-       __jhash_mix(a, b, c);
-
-       a += (__force u32)daddr->s6_addr32[2];
-       b += (__force u32)daddr->s6_addr32[3];
-       c += (__force u32)id;
-       __jhash_mix(a, b, c);
-
-       return c & (INETFRAGS_HASHSZ - 1);
-}
-
 static unsigned int nf_hashfn(struct inet_frag_queue *q)
 {
        const struct nf_ct_frag6_queue *nq;
 
        nq = container_of(q, struct nf_ct_frag6_queue, q);
-       return ip6qhashfn(nq->id, &nq->saddr, &nq->daddr);
+       return inet6_hash_frag(nq->id, &nq->saddr, &nq->daddr, nf_frags.rnd);
 }
 
 static void nf_skb_free(struct sk_buff *skb)
@@ -209,7 +181,7 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
        arg.dst = dst;
 
        read_lock_bh(&nf_frags.lock);
-       hash = ip6qhashfn(id, src, dst);
+       hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
 
        q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
        local_bh_enable();
index 89184b576e2377f1190c69a36476d320e263c265..2eeadfa039cbb0e84e81efe33eaca668b93d26a7 100644 (file)
@@ -99,8 +99,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
  * callers should be careful not to use the hash value outside the ipfrag_lock
  * as doing so could race with ipfrag_hash_rnd being recalculated.
  */
-static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
-                              struct in6_addr *daddr)
+unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr,
+                            const struct in6_addr *daddr, u32 rnd)
 {
        u32 a, b, c;
 
@@ -110,7 +110,7 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
 
        a += JHASH_GOLDEN_RATIO;
        b += JHASH_GOLDEN_RATIO;
-       c += ip6_frags.rnd;
+       c += rnd;
        __jhash_mix(a, b, c);
 
        a += (__force u32)saddr->s6_addr32[3];
@@ -125,13 +125,14 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
 
        return c & (INETFRAGS_HASHSZ - 1);
 }
+EXPORT_SYMBOL_GPL(inet6_hash_frag);
 
 static unsigned int ip6_hashfn(struct inet_frag_queue *q)
 {
        struct frag_queue *fq;
 
        fq = container_of(q, struct frag_queue, q);
-       return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr);
+       return inet6_hash_frag(fq->id, &fq->saddr, &fq->daddr, ip6_frags.rnd);
 }
 
 int ip6_frag_match(struct inet_frag_queue *q, void *a)
@@ -247,7 +248,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
        arg.dst = dst;
 
        read_lock(&ip6_frags.lock);
-       hash = ip6qhashfn(id, src, dst);
+       hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
 
        q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
        if (q == NULL)
index 776871ee22886f41631504fd6a9b740d909df9d7..f4385a6569c2c0531ddefdd530f999768d359f88 100644 (file)
@@ -2708,6 +2708,8 @@ int __init ip6_route_init(void)
        if (ret)
                goto out_kmem_cache;
 
+       ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
+
        /* Registering of the loopback is done before this portion of code,
         * the loopback reference in rt6_info will not be taken, do it
         * manually for init_net */
index e85f377a8f82c671a3eb3d99698fa443632d51fc..df16b68644e79dc5a52801ddc5334d866860223e 100644 (file)
@@ -1050,7 +1050,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
        struct tcphdr *th = tcp_hdr(skb), *t1;
        struct sk_buff *buff;
        struct flowi fl;
-       struct net *net = dev_net(skb->dev);
+       struct net *net = dev_net(skb->dst->dev);
        struct sock *ctl_sk = net->ipv6.tcp_sk;
        unsigned int tot_len = sizeof(struct tcphdr);
        __be32 *topt;
index 705959b31e24dab7cd85db52b1b098391cfa2489..d7b54b5bfa69954778a7eed398d23e06fa18633c 100644 (file)
@@ -524,7 +524,6 @@ static int iucv_enable(void)
        get_online_cpus();
        for_each_online_cpu(cpu)
                smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1);
-       preempt_enable();
        if (cpus_empty(iucv_buffer_cpumask))
                /* No cpu could declare an iucv buffer. */
                goto out_path;
@@ -547,7 +546,9 @@ out:
  */
 static void iucv_disable(void)
 {
+       get_online_cpus();
        on_each_cpu(iucv_retrieve_cpu, NULL, 1);
+       put_online_cpus();
        kfree(iucv_path_table);
 }
 
index d628df97e02ed5b81002e725bdda6f200649fc08..362fe317e1f38b8b0dda3e291cf8553227b782a4 100644 (file)
@@ -58,6 +58,7 @@ struct pfkey_sock {
                        struct xfrm_policy_walk policy;
                        struct xfrm_state_walk  state;
                } u;
+               struct sk_buff  *skb;
        } dump;
 };
 
@@ -73,22 +74,22 @@ static int pfkey_can_dump(struct sock *sk)
        return 0;
 }
 
-static int pfkey_do_dump(struct pfkey_sock *pfk)
+static void pfkey_terminate_dump(struct pfkey_sock *pfk)
 {
-       int rc;
-
-       rc = pfk->dump.dump(pfk);
-       if (rc == -ENOBUFS)
-               return 0;
-
-       pfk->dump.done(pfk);
-       pfk->dump.dump = NULL;
-       pfk->dump.done = NULL;
-       return rc;
+       if (pfk->dump.dump) {
+               if (pfk->dump.skb) {
+                       kfree_skb(pfk->dump.skb);
+                       pfk->dump.skb = NULL;
+               }
+               pfk->dump.done(pfk);
+               pfk->dump.dump = NULL;
+               pfk->dump.done = NULL;
+       }
 }
 
 static void pfkey_sock_destruct(struct sock *sk)
 {
+       pfkey_terminate_dump(pfkey_sk(sk));
        skb_queue_purge(&sk->sk_receive_queue);
 
        if (!sock_flag(sk, SOCK_DEAD)) {
@@ -310,6 +311,31 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
        return err;
 }
 
+static int pfkey_do_dump(struct pfkey_sock *pfk)
+{
+       struct sadb_msg *hdr;
+       int rc;
+
+       rc = pfk->dump.dump(pfk);
+       if (rc == -ENOBUFS)
+               return 0;
+
+       if (pfk->dump.skb) {
+               if (!pfkey_can_dump(&pfk->sk))
+                       return 0;
+
+               hdr = (struct sadb_msg *) pfk->dump.skb->data;
+               hdr->sadb_msg_seq = 0;
+               hdr->sadb_msg_errno = rc;
+               pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
+                               &pfk->sk);
+               pfk->dump.skb = NULL;
+       }
+
+       pfkey_terminate_dump(pfk);
+       return rc;
+}
+
 static inline void pfkey_hdr_dup(struct sadb_msg *new, struct sadb_msg *orig)
 {
        *new = *orig;
@@ -372,6 +398,7 @@ static u8 sadb_ext_min_len[] = {
        [SADB_X_EXT_NAT_T_DPORT]        = (u8) sizeof(struct sadb_x_nat_t_port),
        [SADB_X_EXT_NAT_T_OA]           = (u8) sizeof(struct sadb_address),
        [SADB_X_EXT_SEC_CTX]            = (u8) sizeof(struct sadb_x_sec_ctx),
+       [SADB_X_EXT_KMADDRESS]          = (u8) sizeof(struct sadb_x_kmaddress),
 };
 
 /* Verify sadb_address_{len,prefixlen} against sa_family.  */
@@ -1736,9 +1763,14 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr)
        out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
        out_hdr->sadb_msg_errno = 0;
        out_hdr->sadb_msg_reserved = 0;
-       out_hdr->sadb_msg_seq = count;
+       out_hdr->sadb_msg_seq = count + 1;
        out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
-       pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk);
+
+       if (pfk->dump.skb)
+               pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
+                               &pfk->sk);
+       pfk->dump.skb = out_skb;
+
        return 0;
 }
 
@@ -2237,7 +2269,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
        return 0;
 
 out:
-       xp->dead = 1;
+       xp->walk.dead = 1;
        xfrm_policy_destroy(xp);
        return err;
 }
@@ -2353,24 +2385,21 @@ static int pfkey_sockaddr_pair_size(sa_family_t family)
        return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2);
 }
 
-static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq,
+static int parse_sockaddr_pair(struct sockaddr *sa, int ext_len,
                               xfrm_address_t *saddr, xfrm_address_t *daddr,
                               u16 *family)
 {
-       u8 *sa = (u8 *) (rq + 1);
        int af, socklen;
 
-       if (rq->sadb_x_ipsecrequest_len <
-           pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family))
+       if (ext_len < pfkey_sockaddr_pair_size(sa->sa_family))
                return -EINVAL;
 
-       af = pfkey_sockaddr_extract((struct sockaddr *) sa,
-                                   saddr);
+       af = pfkey_sockaddr_extract(sa, saddr);
        if (!af)
                return -EINVAL;
 
        socklen = pfkey_sockaddr_len(af);
-       if (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen),
+       if (pfkey_sockaddr_extract((struct sockaddr *) (((u8 *)sa) + socklen),
                                   daddr) != af)
                return -EINVAL;
 
@@ -2390,7 +2419,9 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
                return -EINVAL;
 
        /* old endoints */
-       err = parse_sockaddr_pair(rq1, &m->old_saddr, &m->old_daddr,
+       err = parse_sockaddr_pair((struct sockaddr *)(rq1 + 1),
+                                 rq1->sadb_x_ipsecrequest_len,
+                                 &m->old_saddr, &m->old_daddr,
                                  &m->old_family);
        if (err)
                return err;
@@ -2403,7 +2434,9 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
                return -EINVAL;
 
        /* new endpoints */
-       err = parse_sockaddr_pair(rq2, &m->new_saddr, &m->new_daddr,
+       err = parse_sockaddr_pair((struct sockaddr *)(rq2 + 1),
+                                 rq2->sadb_x_ipsecrequest_len,
+                                 &m->new_saddr, &m->new_daddr,
                                  &m->new_family);
        if (err)
                return err;
@@ -2429,29 +2462,40 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
        int i, len, ret, err = -EINVAL;
        u8 dir;
        struct sadb_address *sa;
+       struct sadb_x_kmaddress *kma;
        struct sadb_x_policy *pol;
        struct sadb_x_ipsecrequest *rq;
        struct xfrm_selector sel;
        struct xfrm_migrate m[XFRM_MAX_DEPTH];
+       struct xfrm_kmaddress k;
 
        if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1],
-           ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) ||
+                                    ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) ||
            !ext_hdrs[SADB_X_EXT_POLICY - 1]) {
                err = -EINVAL;
                goto out;
        }
 
+       kma = ext_hdrs[SADB_X_EXT_KMADDRESS - 1];
        pol = ext_hdrs[SADB_X_EXT_POLICY - 1];
-       if (!pol) {
-               err = -EINVAL;
-               goto out;
-       }
 
        if (pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) {
                err = -EINVAL;
                goto out;
        }
 
+       if (kma) {
+               /* convert sadb_x_kmaddress to xfrm_kmaddress */
+               k.reserved = kma->sadb_x_kmaddress_reserved;
+               ret = parse_sockaddr_pair((struct sockaddr *)(kma + 1),
+                                         8*(kma->sadb_x_kmaddress_len) - sizeof(*kma),
+                                         &k.local, &k.remote, &k.family);
+               if (ret < 0) {
+                       err = ret;
+                       goto out;
+               }
+       }
+
        dir = pol->sadb_x_policy_dir - 1;
        memset(&sel, 0, sizeof(sel));
 
@@ -2496,7 +2540,8 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
                goto out;
        }
 
-       return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i);
+       return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
+                           kma ? &k : NULL);
 
  out:
        return err;
@@ -2575,9 +2620,14 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
        out_hdr->sadb_msg_type = SADB_X_SPDDUMP;
        out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
        out_hdr->sadb_msg_errno = 0;
-       out_hdr->sadb_msg_seq = count;
+       out_hdr->sadb_msg_seq = count + 1;
        out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
-       pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk);
+
+       if (pfk->dump.skb)
+               pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
+                               &pfk->sk);
+       pfk->dump.skb = out_skb;
+
        return 0;
 }
 
@@ -3283,6 +3333,32 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
        return 0;
 }
 
+
+static int set_sadb_kmaddress(struct sk_buff *skb, struct xfrm_kmaddress *k)
+{
+       struct sadb_x_kmaddress *kma;
+       u8 *sa;
+       int family = k->family;
+       int socklen = pfkey_sockaddr_len(family);
+       int size_req;
+
+       size_req = (sizeof(struct sadb_x_kmaddress) +
+                   pfkey_sockaddr_pair_size(family));
+
+       kma = (struct sadb_x_kmaddress *)skb_put(skb, size_req);
+       memset(kma, 0, size_req);
+       kma->sadb_x_kmaddress_len = size_req / 8;
+       kma->sadb_x_kmaddress_exttype = SADB_X_EXT_KMADDRESS;
+       kma->sadb_x_kmaddress_reserved = k->reserved;
+
+       sa = (u8 *)(kma + 1);
+       if (!pfkey_sockaddr_fill(&k->local, 0, (struct sockaddr *)sa, family) ||
+           !pfkey_sockaddr_fill(&k->remote, 0, (struct sockaddr *)(sa+socklen), family))
+               return -EINVAL;
+
+       return 0;
+}
+
 static int set_ipsecrequest(struct sk_buff *skb,
                            uint8_t proto, uint8_t mode, int level,
                            uint32_t reqid, uint8_t family,
@@ -3315,7 +3391,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
 
 #ifdef CONFIG_NET_KEY_MIGRATE
 static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
-                             struct xfrm_migrate *m, int num_bundles)
+                             struct xfrm_migrate *m, int num_bundles,
+                             struct xfrm_kmaddress *k)
 {
        int i;
        int sasize_sel;
@@ -3332,6 +3409,12 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
        if (num_bundles <= 0 || num_bundles > XFRM_MAX_DEPTH)
                return -EINVAL;
 
+       if (k != NULL) {
+               /* addresses for KM */
+               size += PFKEY_ALIGN8(sizeof(struct sadb_x_kmaddress) +
+                                    pfkey_sockaddr_pair_size(k->family));
+       }
+
        /* selector */
        sasize_sel = pfkey_sockaddr_size(sel->family);
        if (!sasize_sel)
@@ -3368,6 +3451,10 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
        hdr->sadb_msg_seq = 0;
        hdr->sadb_msg_pid = 0;
 
+       /* Addresses to be used by KM for negotiation, if ext is available */
+       if (k != NULL && (set_sadb_kmaddress(skb, k) < 0))
+               return -EINVAL;
+
        /* selector src */
        set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel);
 
@@ -3413,7 +3500,8 @@ err:
 }
 #else
 static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
-                             struct xfrm_migrate *m, int num_bundles)
+                             struct xfrm_migrate *m, int num_bundles,
+                             struct xfrm_kmaddress *k)
 {
        return -ENOPROTOOPT;
 }
index e2574885db4aba5414aa82722ca9deaffab04275..855126a3039daa16ae64ca60c8087e0439a0d61f 100644 (file)
@@ -82,7 +82,6 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
                                  enum nl80211_iftype type, u32 *flags,
                                  struct vif_params *params)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct net_device *dev;
        struct ieee80211_sub_if_data *sdata;
        int ret;
@@ -95,15 +94,15 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
        if (!nl80211_type_check(type))
                return -EINVAL;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        ret = ieee80211_if_change_type(sdata, type);
        if (ret)
                return ret;
 
+       if (netif_running(sdata->dev))
+               return -EBUSY;
+
        if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
                ieee80211_sdata_set_mesh_id(sdata,
                                            params->mesh_id_len,
@@ -120,16 +119,12 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
                             u8 key_idx, u8 *mac_addr,
                             struct key_params *params)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta = NULL;
        enum ieee80211_key_alg alg;
        struct ieee80211_key *key;
        int err;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        switch (params->cipher) {
@@ -174,14 +169,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
                             u8 key_idx, u8 *mac_addr)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta;
        int ret;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        rcu_read_lock();
@@ -222,7 +213,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
                             void (*callback)(void *cookie,
                                              struct key_params *params))
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta = NULL;
        u8 seq[6] = {0};
@@ -232,9 +222,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
        u16 iv16;
        int err = -ENOENT;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        rcu_read_lock();
@@ -310,12 +297,8 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
                                        struct net_device *dev,
                                        u8 key_idx)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        rcu_read_lock();
 
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -496,13 +479,9 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
 static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
                                struct beacon_parameters *params)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        struct beacon_data *old;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (sdata->vif.type != NL80211_IFTYPE_AP)
@@ -519,13 +498,9 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
 static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
                                struct beacon_parameters *params)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        struct beacon_data *old;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (sdata->vif.type != NL80211_IFTYPE_AP)
@@ -541,13 +516,9 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
 
 static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        struct beacon_data *old;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (sdata->vif.type != NL80211_IFTYPE_AP)
@@ -695,9 +666,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
        int err;
 
-       if (dev == local->mdev || params->vlan == local->mdev)
-               return -EOPNOTSUPP;
-
        /* Prevent a race with changing the rate control algorithm */
        if (!netif_running(dev))
                return -ENETDOWN;
@@ -725,7 +693,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
 
        sta_apply_parameters(local, sta, params);
 
-       rate_control_rate_init(sta, local);
+       rate_control_rate_init(sta);
 
        rcu_read_lock();
 
@@ -752,9 +720,6 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (mac) {
@@ -786,9 +751,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
        struct sta_info *sta;
        struct ieee80211_sub_if_data *vlansdata;
 
-       if (dev == local->mdev || params->vlan == local->mdev)
-               return -EOPNOTSUPP;
-
        rcu_read_lock();
 
        /* XXX: get sta belonging to dev */
@@ -828,9 +790,6 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
        struct sta_info *sta;
        int err;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        if (!netif_running(dev))
                return -ENETDOWN;
 
@@ -884,9 +843,6 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
        struct mesh_path *mpath;
        struct sta_info *sta;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        if (!netif_running(dev))
                return -ENETDOWN;
 
@@ -958,13 +914,9 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
                               u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
 
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        struct mesh_path *mpath;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
@@ -986,13 +938,9 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
                                 int idx, u8 *dst, u8 *next_hop,
                                 struct mpath_info *pinfo)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        struct mesh_path *mpath;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
@@ -1015,13 +963,9 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
                                struct net_device *dev,
                                struct bss_parameters *params)
 {
-       struct ieee80211_local *local = wiphy_priv(wiphy);
        struct ieee80211_sub_if_data *sdata;
        u32 changed = 0;
 
-       if (dev == local->mdev)
-               return -EOPNOTSUPP;
-
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (sdata->vif.type != NL80211_IFTYPE_AP)
index 81f350eaf8a3dfc68b8b2e8c94d1cd9794828c82..b9902e425f096f336f93c97aa2a4494508de4272 100644 (file)
@@ -173,8 +173,7 @@ static ssize_t sta_agg_status_write(struct file *file,
                const char __user *user_buf, size_t count, loff_t *ppos)
 {
        struct sta_info *sta = file->private_data;
-       struct net_device *dev = sta->sdata->dev;
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_local *local = sta->sdata->local;
        struct ieee80211_hw *hw = &local->hw;
        u8 *da = sta->sta.addr;
        static int tid_static_tx[16] = {0, 0, 0, 0, 0, 0, 0, 0,
index 3912fba6d3d0b27c40816d36ffc327073bae125e..8025b294588bc0e1c44b61bfb465085cb0184c84 100644 (file)
@@ -573,6 +573,10 @@ enum {
 /* maximum number of hardware queues we support. */
 #define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
 
+struct ieee80211_master_priv {
+       struct ieee80211_local *local;
+};
+
 struct ieee80211_local {
        /* embed the driver visible part.
         * don't cast (use the static inlines below), but we keep
@@ -720,6 +724,8 @@ struct ieee80211_local {
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct local_debugfsdentries {
+               struct dentry *rcdir;
+               struct dentry *rcname;
                struct dentry *frequency;
                struct dentry *antenna_sel_tx;
                struct dentry *antenna_sel_rx;
index a72fbebb8ea2bd199b5aac9f53ece22e88ab57ed..8336fee68d3e05b717047e4d8a1ac5f3623542a8 100644 (file)
@@ -58,8 +58,9 @@ static inline int identical_mac_addr_allowed(int type1, int type2)
 
 static int ieee80211_open(struct net_device *dev)
 {
-       struct ieee80211_sub_if_data *sdata, *nsdata;
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_sub_if_data *nsdata;
+       struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
        struct ieee80211_if_init_conf conf;
        u32 changed = 0;
@@ -67,8 +68,6 @@ static int ieee80211_open(struct net_device *dev)
        bool need_hw_reconfig = 0;
        u8 null_addr[ETH_ALEN] = {0};
 
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
        /* fail early if user set an invalid address */
        if (compare_ether_addr(dev->dev_addr, null_addr) &&
            !is_valid_ether_addr(dev->dev_addr))
@@ -512,8 +511,8 @@ static int ieee80211_stop(struct net_device *dev)
 
 static void ieee80211_set_multicast_list(struct net_device *dev)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_local *local = sdata->local;
        int allmulti, promisc, sdata_allmulti, sdata_promisc;
 
        allmulti = !!(dev->flags & IFF_ALLMULTI);
@@ -625,6 +624,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
        /* and set some type-dependent values */
        sdata->vif.type = type;
        sdata->dev->hard_start_xmit = ieee80211_subif_start_xmit;
+       sdata->wdev.iftype = type;
 
        /* only monitor differs */
        sdata->dev->type = ARPHRD_ETHER;
index c307dba7ec034ce215975c26af7b86012dfd82be..d608c44047c0673aa28f7985319064c3ebbacd0d 100644 (file)
@@ -106,7 +106,8 @@ static const struct header_ops ieee80211_header_ops = {
 
 static int ieee80211_master_open(struct net_device *dev)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_master_priv *mpriv = netdev_priv(dev);
+       struct ieee80211_local *local = mpriv->local;
        struct ieee80211_sub_if_data *sdata;
        int res = -EOPNOTSUPP;
 
@@ -128,7 +129,8 @@ static int ieee80211_master_open(struct net_device *dev)
 
 static int ieee80211_master_stop(struct net_device *dev)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_master_priv *mpriv = netdev_priv(dev);
+       struct ieee80211_local *local = mpriv->local;
        struct ieee80211_sub_if_data *sdata;
 
        /* we hold the RTNL here so can safely walk the list */
@@ -141,7 +143,8 @@ static int ieee80211_master_stop(struct net_device *dev)
 
 static void ieee80211_master_set_multicast_list(struct net_device *dev)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_master_priv *mpriv = netdev_priv(dev);
+       struct ieee80211_local *local = mpriv->local;
 
        ieee80211_configure_filter(local);
 }
@@ -539,6 +542,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        u16 frag, type;
        __le16 fc;
+       struct ieee80211_supported_band *sband;
        struct ieee80211_tx_status_rtap_hdr *rthdr;
        struct ieee80211_sub_if_data *sdata;
        struct net_device *prev_dev = NULL;
@@ -585,7 +589,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
                        sta->tx_retry_count += info->status.retry_count;
                }
 
-               rate_control_tx_status(local->mdev, skb);
+               sband = local->hw.wiphy->bands[info->band];
+               rate_control_tx_status(local, sband, sta, skb);
        }
 
        rcu_read_unlock();
@@ -787,7 +792,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        int result;
        enum ieee80211_band band;
        struct net_device *mdev;
-       struct wireless_dev *mwdev;
+       struct ieee80211_master_priv *mpriv;
 
        /*
         * generic code guarantees at least one band,
@@ -829,16 +834,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        if (hw->queues < 4)
                hw->ampdu_queues = 0;
 
-       mdev = alloc_netdev_mq(sizeof(struct wireless_dev),
+       mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv),
                               "wmaster%d", ether_setup,
                               ieee80211_num_queues(hw));
        if (!mdev)
                goto fail_mdev_alloc;
 
-       mwdev = netdev_priv(mdev);
-       mdev->ieee80211_ptr = mwdev;
-       mwdev->wiphy = local->hw.wiphy;
-
+       mpriv = netdev_priv(mdev);
+       mpriv->local = local;
        local->mdev = mdev;
 
        ieee80211_rx_bss_list_init(local);
index 30cf891fd3a8a71be770abd304879edd895b87ca..8013277924f2d75fca8acca678cbebb079c0f8a4 100644 (file)
@@ -351,7 +351,7 @@ static void ieee80211_mesh_path_timer(unsigned long data)
        struct ieee80211_sub_if_data *sdata =
                (struct ieee80211_sub_if_data *) data;
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
-       struct ieee80211_local *local = wdev_priv(&sdata->wdev);
+       struct ieee80211_local *local = sdata->local;
 
        queue_work(local->hw.workqueue, &ifmsh->work);
 }
index 8ee414a0447c83ae77f5ec4dbda727f5f15defc6..e10471c6ba42457894ebca93db6a7f8c9376323f 100644 (file)
@@ -71,6 +71,7 @@ enum mesh_path_flags {
  */
 struct mesh_path {
        u8 dst[ETH_ALEN];
+       u8 mpp[ETH_ALEN];       /* used for MPP or MAP */
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *next_hop;
        struct timer_list timer;
@@ -226,6 +227,9 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
 void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata);
 struct mesh_path *mesh_path_lookup(u8 *dst,
                struct ieee80211_sub_if_data *sdata);
+struct mesh_path *mpp_path_lookup(u8 *dst,
+                                 struct ieee80211_sub_if_data *sdata);
+int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata);
 struct mesh_path *mesh_path_lookup_by_idx(int idx,
                struct ieee80211_sub_if_data *sdata);
 void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
index e4fa2905fadc4d8b844a9325a66c1fa1705ef6ce..3c72557df45adee87cba306b2d560089e71cdb49 100644 (file)
@@ -36,6 +36,7 @@ struct mpath_node {
 };
 
 static struct mesh_table *mesh_paths;
+static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
 
 /* This lock will have the grow table function as writer and add / delete nodes
  * as readers. When reading the table (i.e. doing lookups) we are well protected
@@ -94,6 +95,34 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
        return NULL;
 }
 
+struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
+{
+       struct mesh_path *mpath;
+       struct hlist_node *n;
+       struct hlist_head *bucket;
+       struct mesh_table *tbl;
+       struct mpath_node *node;
+
+       tbl = rcu_dereference(mpp_paths);
+
+       bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)];
+       hlist_for_each_entry_rcu(node, n, bucket, list) {
+               mpath = node->mpath;
+               if (mpath->sdata == sdata &&
+                   memcmp(dst, mpath->dst, ETH_ALEN) == 0) {
+                       if (MPATH_EXPIRED(mpath)) {
+                               spin_lock_bh(&mpath->state_lock);
+                               if (MPATH_EXPIRED(mpath))
+                                       mpath->flags &= ~MESH_PATH_ACTIVE;
+                               spin_unlock_bh(&mpath->state_lock);
+                       }
+                       return mpath;
+               }
+       }
+       return NULL;
+}
+
+
 /**
  * mesh_path_lookup_by_idx - look up a path in the mesh path table by its index
  * @idx: index
@@ -226,6 +255,91 @@ err_path_alloc:
 }
 
 
+int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
+{
+       struct mesh_path *mpath, *new_mpath;
+       struct mpath_node *node, *new_node;
+       struct hlist_head *bucket;
+       struct hlist_node *n;
+       int grow = 0;
+       int err = 0;
+       u32 hash_idx;
+
+
+       if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0)
+               /* never add ourselves as neighbours */
+               return -ENOTSUPP;
+
+       if (is_multicast_ether_addr(dst))
+               return -ENOTSUPP;
+
+       err = -ENOMEM;
+       new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
+       if (!new_mpath)
+               goto err_path_alloc;
+
+       new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
+       if (!new_node)
+               goto err_node_alloc;
+
+       read_lock(&pathtbl_resize_lock);
+       memcpy(new_mpath->dst, dst, ETH_ALEN);
+       memcpy(new_mpath->mpp, mpp, ETH_ALEN);
+       new_mpath->sdata = sdata;
+       new_mpath->flags = 0;
+       skb_queue_head_init(&new_mpath->frame_queue);
+       new_node->mpath = new_mpath;
+       new_mpath->exp_time = jiffies;
+       spin_lock_init(&new_mpath->state_lock);
+
+       hash_idx = mesh_table_hash(dst, sdata, mpp_paths);
+       bucket = &mpp_paths->hash_buckets[hash_idx];
+
+       spin_lock(&mpp_paths->hashwlock[hash_idx]);
+
+       err = -EEXIST;
+       hlist_for_each_entry(node, n, bucket, list) {
+               mpath = node->mpath;
+               if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
+                       goto err_exists;
+       }
+
+       hlist_add_head_rcu(&new_node->list, bucket);
+       if (atomic_inc_return(&mpp_paths->entries) >=
+               mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1))
+               grow = 1;
+
+       spin_unlock(&mpp_paths->hashwlock[hash_idx]);
+       read_unlock(&pathtbl_resize_lock);
+       if (grow) {
+               struct mesh_table *oldtbl, *newtbl;
+
+               write_lock(&pathtbl_resize_lock);
+               oldtbl = mpp_paths;
+               newtbl = mesh_table_grow(mpp_paths);
+               if (!newtbl) {
+                       write_unlock(&pathtbl_resize_lock);
+                       return 0;
+               }
+               rcu_assign_pointer(mpp_paths, newtbl);
+               write_unlock(&pathtbl_resize_lock);
+
+               synchronize_rcu();
+               mesh_table_free(oldtbl, false);
+       }
+       return 0;
+
+err_exists:
+       spin_unlock(&mpp_paths->hashwlock[hash_idx]);
+       read_unlock(&pathtbl_resize_lock);
+       kfree(new_node);
+err_node_alloc:
+       kfree(new_mpath);
+err_path_alloc:
+       return err;
+}
+
+
 /**
  * mesh_plink_broken - deactivates paths and sends perr when a link breaks
  *
@@ -475,11 +589,21 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl)
 int mesh_pathtbl_init(void)
 {
        mesh_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER);
+       if (!mesh_paths)
+               return -ENOMEM;
        mesh_paths->free_node = &mesh_path_node_free;
        mesh_paths->copy_node = &mesh_path_node_copy;
        mesh_paths->mean_chain_len = MEAN_CHAIN_LEN;
-       if (!mesh_paths)
+
+       mpp_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER);
+       if (!mpp_paths) {
+               mesh_table_free(mesh_paths, true);
                return -ENOMEM;
+       }
+       mpp_paths->free_node = &mesh_path_node_free;
+       mpp_paths->copy_node = &mesh_path_node_copy;
+       mpp_paths->mean_chain_len = MEAN_CHAIN_LEN;
+
        return 0;
 }
 
@@ -511,4 +635,5 @@ void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
 void mesh_pathtbl_unregister(void)
 {
        mesh_table_free(mesh_paths, true);
+       mesh_table_free(mpp_paths, true);
 }
index 8611a8318c9c3d9b2b2e66a5237543a1123574e3..e859a0ab6162f273563790fccad473e9f2277c35 100644 (file)
@@ -942,8 +942,8 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
                                disassoc = 1;
                        } else
                                ieee80211_send_probe_req(sdata, ifsta->bssid,
-                                                        local->scan_ssid,
-                                                        local->scan_ssid_len);
+                                                        ifsta->ssid,
+                                                        ifsta->ssid_len);
                        ifsta->flags ^= IEEE80211_STA_PROBEREQ_POLL;
                } else {
                        ifsta->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
@@ -1323,7 +1323,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
        }
 
-       rate_control_rate_init(sta, local);
+       rate_control_rate_init(sta);
 
        if (elems.wmm_param) {
                set_sta_flags(sta, WLAN_STA_WME);
@@ -1452,6 +1452,8 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
        mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
 
+       ieee80211_led_assoc(local, true);
+
        memset(&wrqu, 0, sizeof(wrqu));
        memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
        wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
@@ -2342,7 +2344,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
        sta->sta.supp_rates[band] = supp_rates |
                        ieee80211_mandatory_rates(local, band);
 
-       rate_control_rate_init(sta, local);
+       rate_control_rate_init(sta);
 
        if (sta_info_insert(sta))
                return NULL;
index 0388c090dfe9bb5c1d3437c1137a2abed2ca17bf..5d786720d9357c8ecd96a027074489d338a30951 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/rtnetlink.h>
 #include "rate.h"
 #include "ieee80211_i.h"
+#include "debugfs.h"
 
 struct rate_control_alg {
        struct list_head list;
@@ -127,19 +128,46 @@ static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops)
        module_put(ops->module);
 }
 
+#ifdef CONFIG_MAC80211_DEBUGFS
+static ssize_t rcname_read(struct file *file, char __user *userbuf,
+                          size_t count, loff_t *ppos)
+{
+       struct rate_control_ref *ref = file->private_data;
+       int len = strlen(ref->ops->name);
+
+       return simple_read_from_buffer(userbuf, count, ppos,
+                                      ref->ops->name, len);
+}
+
+static const struct file_operations rcname_ops = {
+       .read = rcname_read,
+       .open = mac80211_open_file_generic,
+};
+#endif
+
 struct rate_control_ref *rate_control_alloc(const char *name,
                                            struct ieee80211_local *local)
 {
+       struct dentry *debugfsdir = NULL;
        struct rate_control_ref *ref;
 
        ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
        if (!ref)
                goto fail_ref;
        kref_init(&ref->kref);
+       ref->local = local;
        ref->ops = ieee80211_rate_control_ops_get(name);
        if (!ref->ops)
                goto fail_ops;
-       ref->priv = ref->ops->alloc(local);
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir);
+       local->debugfs.rcdir = debugfsdir;
+       local->debugfs.rcname = debugfs_create_file("name", 0400, debugfsdir,
+                                                   ref, &rcname_ops);
+#endif
+
+       ref->priv = ref->ops->alloc(&local->hw, debugfsdir);
        if (!ref->priv)
                goto fail_priv;
        return ref;
@@ -158,29 +186,46 @@ static void rate_control_release(struct kref *kref)
 
        ctrl_ref = container_of(kref, struct rate_control_ref, kref);
        ctrl_ref->ops->free(ctrl_ref->priv);
+
+#ifdef CONFIG_MAC80211_DEBUGFS
+       debugfs_remove(ctrl_ref->local->debugfs.rcname);
+       ctrl_ref->local->debugfs.rcname = NULL;
+       debugfs_remove(ctrl_ref->local->debugfs.rcdir);
+       ctrl_ref->local->debugfs.rcdir = NULL;
+#endif
+
        ieee80211_rate_control_ops_put(ctrl_ref->ops);
        kfree(ctrl_ref);
 }
 
-void rate_control_get_rate(struct net_device *dev,
+void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
                           struct ieee80211_supported_band *sband,
-                          struct sk_buff *skb,
+                          struct sta_info *sta, struct sk_buff *skb,
                           struct rate_selection *sel)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct rate_control_ref *ref = local->rate_ctrl;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct sta_info *sta;
+       struct rate_control_ref *ref = sdata->local->rate_ctrl;
+       void *priv_sta = NULL;
+       struct ieee80211_sta *ista = NULL;
        int i;
 
-       rcu_read_lock();
-       sta = sta_info_get(local, hdr->addr1);
-
        sel->rate_idx = -1;
        sel->nonerp_idx = -1;
        sel->probe_idx = -1;
+       sel->max_rate_idx = sdata->max_ratectrl_rateidx;
+
+       if (sta) {
+               ista = &sta->sta;
+               priv_sta = sta->rate_ctrl_priv;
+       }
+
+       if (sta && sdata->force_unicast_rateidx > -1)
+               sel->rate_idx = sdata->force_unicast_rateidx;
+       else
+               ref->ops->get_rate(ref->priv, sband, ista, priv_sta, skb, sel);
 
-       ref->ops->get_rate(ref->priv, dev, sband, skb, sel);
+       if (sdata->max_ratectrl_rateidx > -1 &&
+           sel->rate_idx > sdata->max_ratectrl_rateidx)
+               sel->rate_idx = sdata->max_ratectrl_rateidx;
 
        BUG_ON(sel->rate_idx < 0);
 
@@ -191,13 +236,11 @@ void rate_control_get_rate(struct net_device *dev,
                        if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate)
                                break;
 
-                       if (rate_supported(sta, sband->band, i) &&
+                       if (rate_supported(ista, sband->band, i) &&
                            !(rate->flags & IEEE80211_RATE_ERP_G))
                                sel->nonerp_idx = i;
                }
        }
-
-       rcu_read_unlock();
 }
 
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
index 5f18c27eb9000ac621ecaecf3b3cfa738cd1146e..eb94e584d24e866106a561cce50b5c91e0e10980 100644 (file)
 #include "ieee80211_i.h"
 #include "sta_info.h"
 
-/**
- * struct rate_selection - rate selection for rate control algos
- * @rate: selected transmission rate index
- * @nonerp: Non-ERP rate to use instead if ERP cannot be used
- * @probe: rate for probing (or -1)
- *
- */
-struct rate_selection {
-       s8 rate_idx, nonerp_idx, probe_idx;
-};
-
-struct rate_control_ops {
-       struct module *module;
-       const char *name;
-       void (*tx_status)(void *priv, struct net_device *dev,
-                         struct sk_buff *skb);
-       void (*get_rate)(void *priv, struct net_device *dev,
-                        struct ieee80211_supported_band *band,
-                        struct sk_buff *skb,
-                        struct rate_selection *sel);
-       void (*rate_init)(void *priv, void *priv_sta,
-                         struct ieee80211_local *local, struct sta_info *sta);
-       void (*clear)(void *priv);
-
-       void *(*alloc)(struct ieee80211_local *local);
-       void (*free)(void *priv);
-       void *(*alloc_sta)(void *priv, gfp_t gfp);
-       void (*free_sta)(void *priv, void *priv_sta);
-
-       int (*add_attrs)(void *priv, struct kobject *kobj);
-       void (*remove_attrs)(void *priv, struct kobject *kobj);
-       void (*add_sta_debugfs)(void *priv, void *priv_sta,
-                               struct dentry *dir);
-       void (*remove_sta_debugfs)(void *priv, void *priv_sta);
-};
-
 struct rate_control_ref {
+       struct ieee80211_local *local;
        struct rate_control_ops *ops;
        void *priv;
        struct kref kref;
 };
 
-int ieee80211_rate_control_register(struct rate_control_ops *ops);
-void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
-
 /* Get a reference to the rate control algorithm. If `name' is NULL, get the
  * first available algorithm. */
 struct rate_control_ref *rate_control_alloc(const char *name,
                                            struct ieee80211_local *local);
-void rate_control_get_rate(struct net_device *dev,
+void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
                           struct ieee80211_supported_band *sband,
-                          struct sk_buff *skb,
+                          struct sta_info *sta, struct sk_buff *skb,
                           struct rate_selection *sel);
 struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
 void rate_control_put(struct rate_control_ref *ref);
 
-static inline void rate_control_tx_status(struct net_device *dev,
+static inline void rate_control_tx_status(struct ieee80211_local *local,
+                                         struct ieee80211_supported_band *sband,
+                                         struct sta_info *sta,
                                          struct sk_buff *skb)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct rate_control_ref *ref = local->rate_ctrl;
+       struct ieee80211_sta *ista = &sta->sta;
+       void *priv_sta = sta->rate_ctrl_priv;
 
-       ref->ops->tx_status(ref->priv, dev, skb);
+       ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
 }
 
 
-static inline void rate_control_rate_init(struct sta_info *sta,
-                                         struct ieee80211_local *local)
+static inline void rate_control_rate_init(struct sta_info *sta)
 {
+       struct ieee80211_local *local = sta->sdata->local;
        struct rate_control_ref *ref = sta->rate_ctrl;
-       ref->ops->rate_init(ref->priv, sta->rate_ctrl_priv, local, sta);
+       struct ieee80211_sta *ista = &sta->sta;
+       void *priv_sta = sta->rate_ctrl_priv;
+       struct ieee80211_supported_band *sband;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+       ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
 }
 
 
@@ -100,15 +71,19 @@ static inline void rate_control_clear(struct ieee80211_local *local)
 }
 
 static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
+                                          struct ieee80211_sta *sta,
                                           gfp_t gfp)
 {
-       return ref->ops->alloc_sta(ref->priv, gfp);
+       return ref->ops->alloc_sta(ref->priv, sta, gfp);
 }
 
-static inline void rate_control_free_sta(struct rate_control_ref *ref,
-                                        void *priv)
+static inline void rate_control_free_sta(struct sta_info *sta)
 {
-       ref->ops->free_sta(ref->priv, priv);
+       struct rate_control_ref *ref = sta->rate_ctrl;
+       struct ieee80211_sta *ista = &sta->sta;
+       void *priv_sta = sta->rate_ctrl_priv;
+
+       ref->ops->free_sta(ref->priv, ista, priv_sta);
 }
 
 static inline void rate_control_add_sta_debugfs(struct sta_info *sta)
@@ -130,31 +105,6 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
 #endif
 }
 
-static inline int rate_supported(struct sta_info *sta,
-                                enum ieee80211_band band,
-                                int index)
-{
-       return (sta == NULL || sta->sta.supp_rates[band] & BIT(index));
-}
-
-static inline s8
-rate_lowest_index(struct ieee80211_local *local,
-                 struct ieee80211_supported_band *sband,
-                 struct sta_info *sta)
-{
-       int i;
-
-       for (i = 0; i < sband->n_bitrates; i++)
-               if (rate_supported(sta, sband->band, i))
-                       return i;
-
-       /* warn when we cannot find a rate. */
-       WARN_ON(1);
-
-       return 0;
-}
-
-
 /* functions for rate control related to a device */
 int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
                                 const char *name);
index ffafc5da572ec83f624a80a4b9fbd521cdfc3b26..01d64d53f3b9351ead2458fcebf2b1b5301a1f4b 100644 (file)
@@ -124,7 +124,6 @@ struct rc_pid_events_file_info {
  * struct rc_pid_debugfs_entries - tunable parameters
  *
  * Algorithm parameters, tunable via debugfs.
- * @dir: the debugfs directory for a specific phy
  * @target: target percentage for failed frames
  * @sampling_period: error sampling interval in milliseconds
  * @coeff_p: absolute value of the proportional coefficient
@@ -143,7 +142,6 @@ struct rc_pid_events_file_info {
  *     ordering of rates)
  */
 struct rc_pid_debugfs_entries {
-       struct dentry *dir;
        struct dentry *target;
        struct dentry *sampling_period;
        struct dentry *coeff_p;
index bc1c4569caa18c12557e94aef051e54436816a4c..86eb374e3b87f22338b4697552e0283f897db8aa 100644 (file)
  * exhibited a worse failed frames behaviour and we'll choose the highest rate
  * whose failed frames behaviour is not worse than the one of the original rate
  * target. While at it, check that the new rate is valid. */
-static void rate_control_pid_adjust_rate(struct ieee80211_local *local,
-                                        struct sta_info *sta, int adj,
+static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband,
+                                        struct ieee80211_sta *sta,
+                                        struct rc_pid_sta_info *spinfo, int adj,
                                         struct rc_pid_rateinfo *rinfo)
 {
-       struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_supported_band *sband;
        int cur_sorted, new_sorted, probe, tmp, n_bitrates, band;
-       struct rc_pid_sta_info *spinfo = (void *)sta->rate_ctrl_priv;
        int cur = spinfo->txrate_idx;
 
-       sdata = sta->sdata;
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
        band = sband->band;
        n_bitrates = sband->n_bitrates;
 
@@ -146,13 +142,11 @@ static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
 }
 
 static void rate_control_pid_sample(struct rc_pid_info *pinfo,
-                                   struct ieee80211_local *local,
-                                   struct sta_info *sta)
+                                   struct ieee80211_supported_band *sband,
+                                   struct ieee80211_sta *sta,
+                                   struct rc_pid_sta_info *spinfo)
 {
-       struct ieee80211_sub_if_data *sdata = sta->sdata;
-       struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv;
        struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
-       struct ieee80211_supported_band *sband;
        u32 pf;
        s32 err_avg;
        u32 err_prop;
@@ -161,9 +155,6 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
        int adj, i, j, tmp;
        unsigned long period;
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-       spinfo = sta->rate_ctrl_priv;
-
        /* In case nothing happened during the previous control interval, turn
         * the sharpening factor on. */
        period = (HZ * pinfo->sampling_period + 500) / 1000;
@@ -179,11 +170,15 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
        if (unlikely(spinfo->tx_num_xmit == 0))
                pf = spinfo->last_pf;
        else {
+               /* XXX: BAD HACK!!! */
+               struct sta_info *si = container_of(sta, struct sta_info, sta);
+
                pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
-               if (ieee80211_vif_is_mesh(&sdata->vif) && pf == 100)
-                       mesh_plink_broken(sta);
+
+               if (ieee80211_vif_is_mesh(&si->sdata->vif) && pf == 100)
+                       mesh_plink_broken(si);
                pf <<= RC_PID_ARITH_SHIFT;
-               sta->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
+               si->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
                                        >> RC_PID_ARITH_SHIFT;
        }
 
@@ -229,43 +224,25 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
 
        /* Change rate. */
        if (adj)
-               rate_control_pid_adjust_rate(local, sta, adj, rinfo);
+               rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo);
 }
 
-static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
+static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband,
+                                      struct ieee80211_sta *sta, void *priv_sta,
                                       struct sk_buff *skb)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_sub_if_data *sdata;
        struct rc_pid_info *pinfo = priv;
-       struct sta_info *sta;
-       struct rc_pid_sta_info *spinfo;
+       struct rc_pid_sta_info *spinfo = priv_sta;
        unsigned long period;
-       struct ieee80211_supported_band *sband;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
-       rcu_read_lock();
-
-       sta = sta_info_get(local, hdr->addr1);
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-       if (!sta)
-               goto unlock;
-
-       spinfo = sta->rate_ctrl_priv;
-
-       /* Don't update the state if we're not controlling the rate. */
-       sdata = sta->sdata;
-       if (sdata->force_unicast_rateidx > -1) {
-               spinfo->txrate_idx = sdata->max_ratectrl_rateidx;
-               goto unlock;
-       }
+       if (!spinfo)
+               return;
 
        /* Ignore all frames that were sent with a different rate than the rate
         * we currently advise mac80211 to use. */
        if (info->tx_rate_idx != spinfo->txrate_idx)
-               goto unlock;
+               return;
 
        spinfo->tx_num_xmit++;
 
@@ -289,78 +266,63 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
        if (!period)
                period = 1;
        if (time_after(jiffies, spinfo->last_sample + period))
-               rate_control_pid_sample(pinfo, local, sta);
-
- unlock:
-       rcu_read_unlock();
+               rate_control_pid_sample(pinfo, sband, sta, spinfo);
 }
 
-static void rate_control_pid_get_rate(void *priv, struct net_device *dev,
-                                     struct ieee80211_supported_band *sband,
-                                     struct sk_buff *skb,
-                                     struct rate_selection *sel)
+static void
+rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband,
+                         struct ieee80211_sta *sta, void *priv_sta,
+                         struct sk_buff *skb,
+                         struct rate_selection *sel)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_sub_if_data *sdata;
-       struct rc_pid_sta_info *spinfo;
-       struct sta_info *sta;
+       struct rc_pid_sta_info *spinfo = priv_sta;
        int rateidx;
        u16 fc;
 
-       rcu_read_lock();
-
-       sta = sta_info_get(local, hdr->addr1);
-
        /* Send management frames and broadcast/multicast data using lowest
         * rate. */
        fc = le16_to_cpu(hdr->frame_control);
-       if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-           is_multicast_ether_addr(hdr->addr1) || !sta) {
-               sel->rate_idx = rate_lowest_index(local, sband, sta);
-               rcu_read_unlock();
+       if (!sta || !spinfo ||
+           (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
+           is_multicast_ether_addr(hdr->addr1)) {
+               sel->rate_idx = rate_lowest_index(sband, sta);
                return;
        }
 
-       /* If a forced rate is in effect, select it. */
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       spinfo = (struct rc_pid_sta_info *)sta->rate_ctrl_priv;
-       if (sdata->force_unicast_rateidx > -1)
-               spinfo->txrate_idx = sdata->force_unicast_rateidx;
-
        rateidx = spinfo->txrate_idx;
 
        if (rateidx >= sband->n_bitrates)
                rateidx = sband->n_bitrates - 1;
 
-       rcu_read_unlock();
-
        sel->rate_idx = rateidx;
 
 #ifdef CONFIG_MAC80211_DEBUGFS
-       rate_control_pid_event_tx_rate(
-               &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events,
+       rate_control_pid_event_tx_rate(&spinfo->events,
                rateidx, sband->bitrates[rateidx].bitrate);
 #endif
 }
 
-static void rate_control_pid_rate_init(void *priv, void *priv_sta,
-                                         struct ieee80211_local *local,
-                                         struct sta_info *sta)
+static void
+rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
+                          struct ieee80211_sta *sta, void *priv_sta)
 {
+       struct rc_pid_sta_info *spinfo = priv_sta;
+       struct sta_info *si;
+
        /* TODO: This routine should consider using RSSI from previous packets
         * as we need to have IEEE 802.1X auth succeed immediately after assoc..
         * Until that method is implemented, we will use the lowest supported
         * rate as a workaround. */
-       struct ieee80211_supported_band *sband;
-       struct rc_pid_sta_info *spinfo = (void *)sta->rate_ctrl_priv;
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-       spinfo->txrate_idx = rate_lowest_index(local, sband, sta);
-       sta->fail_avg = 0;
+       spinfo->txrate_idx = rate_lowest_index(sband, sta);
+       /* HACK */
+       si = container_of(sta, struct sta_info, sta);
+       si->fail_avg = 0;
 }
 
-static void *rate_control_pid_alloc(struct ieee80211_local *local)
+static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
+                                   struct dentry *debugfsdir)
 {
        struct rc_pid_info *pinfo;
        struct rc_pid_rateinfo *rinfo;
@@ -371,7 +333,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
        struct rc_pid_debugfs_entries *de;
 #endif
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+       sband = hw->wiphy->bands[hw->conf.channel->band];
 
        pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
        if (!pinfo)
@@ -426,30 +388,28 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
 
 #ifdef CONFIG_MAC80211_DEBUGFS
        de = &pinfo->dentries;
-       de->dir = debugfs_create_dir("rc80211_pid",
-                                    local->hw.wiphy->debugfsdir);
        de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
-                                       de->dir, &pinfo->target);
+                                       debugfsdir, &pinfo->target);
        de->sampling_period = debugfs_create_u32("sampling_period",
-                                                S_IRUSR | S_IWUSR, de->dir,
+                                                S_IRUSR | S_IWUSR, debugfsdir,
                                                 &pinfo->sampling_period);
        de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
-                                        de->dir, &pinfo->coeff_p);
+                                        debugfsdir, &pinfo->coeff_p);
        de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
-                                        de->dir, &pinfo->coeff_i);
+                                        debugfsdir, &pinfo->coeff_i);
        de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
-                                        de->dir, &pinfo->coeff_d);
+                                        debugfsdir, &pinfo->coeff_d);
        de->smoothing_shift = debugfs_create_u32("smoothing_shift",
-                                                S_IRUSR | S_IWUSR, de->dir,
+                                                S_IRUSR | S_IWUSR, debugfsdir,
                                                 &pinfo->smoothing_shift);
        de->sharpen_factor = debugfs_create_u32("sharpen_factor",
-                                              S_IRUSR | S_IWUSR, de->dir,
+                                              S_IRUSR | S_IWUSR, debugfsdir,
                                               &pinfo->sharpen_factor);
        de->sharpen_duration = debugfs_create_u32("sharpen_duration",
-                                                 S_IRUSR | S_IWUSR, de->dir,
+                                                 S_IRUSR | S_IWUSR, debugfsdir,
                                                  &pinfo->sharpen_duration);
        de->norm_offset = debugfs_create_u32("norm_offset",
-                                            S_IRUSR | S_IWUSR, de->dir,
+                                            S_IRUSR | S_IWUSR, debugfsdir,
                                             &pinfo->norm_offset);
 #endif
 
@@ -471,7 +431,6 @@ static void rate_control_pid_free(void *priv)
        debugfs_remove(de->coeff_p);
        debugfs_remove(de->sampling_period);
        debugfs_remove(de->target);
-       debugfs_remove(de->dir);
 #endif
 
        kfree(pinfo->rinfo);
@@ -482,7 +441,8 @@ static void rate_control_pid_clear(void *priv)
 {
 }
 
-static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
+static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta,
+                                       gfp_t gfp)
 {
        struct rc_pid_sta_info *spinfo;
 
@@ -500,10 +460,10 @@ static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
        return spinfo;
 }
 
-static void rate_control_pid_free_sta(void *priv, void *priv_sta)
+static void rate_control_pid_free_sta(void *priv, struct ieee80211_sta *sta,
+                                     void *priv_sta)
 {
-       struct rc_pid_sta_info *spinfo = priv_sta;
-       kfree(spinfo);
+       kfree(priv_sta);
 }
 
 static struct rate_control_ops mac80211_rcpid = {
index 92d898b901e9bbd4d823e873066c4abf37aee00a..77e7b014872b0bd8b2618ff7bfb65c22c56a97dc 100644 (file)
@@ -650,32 +650,28 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
        return result;
 }
 
-static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta)
+static void ap_sta_ps_start(struct sta_info *sta)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = sta->sdata;
        DECLARE_MAC_BUF(mac);
 
-       sdata = sta->sdata;
-
        atomic_inc(&sdata->bss->num_sta_ps);
        set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
        printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n",
-              dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
+              sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 }
 
-static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
+static int ap_sta_ps_end(struct sta_info *sta)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = sta->sdata;
+       struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
        int sent = 0;
-       struct ieee80211_sub_if_data *sdata;
        struct ieee80211_tx_info *info;
        DECLARE_MAC_BUF(mac);
 
-       sdata = sta->sdata;
-
        atomic_dec(&sdata->bss->num_sta_ps);
 
        clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
@@ -685,7 +681,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
 
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
        printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n",
-              dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
+              sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 
        /* Send all buffered frames to the station */
@@ -701,7 +697,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
                sent++;
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
                printk(KERN_DEBUG "%s: STA %s aid %d send PS frame "
-                      "since STA not sleeping anymore\n", dev->name,
+                      "since STA not sleeping anymore\n", sdata->dev->name,
                       print_mac(mac, sta->sta.addr), sta->sta.aid);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
                info->flags |= IEEE80211_TX_CTL_REQUEUE;
@@ -715,7 +711,6 @@ static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
 {
        struct sta_info *sta = rx->sta;
-       struct net_device *dev = rx->dev;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
 
        if (!sta)
@@ -757,10 +752,10 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
                 * exchange sequence */
                if (test_sta_flags(sta, WLAN_STA_PS) &&
                    !ieee80211_has_pm(hdr->frame_control))
-                       rx->sent_ps_buffered += ap_sta_ps_end(dev, sta);
+                       rx->sent_ps_buffered += ap_sta_ps_end(sta);
                else if (!test_sta_flags(sta, WLAN_STA_PS) &&
                         ieee80211_has_pm(hdr->frame_control))
-                       ap_sta_ps_start(dev, sta);
+                       ap_sta_ps_start(sta);
        }
 
        /* Drop data::nullfunc frames silently, since they are used only to
@@ -1112,10 +1107,6 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
 
        hdrlen = ieee80211_hdrlen(hdr->frame_control);
 
-       if (ieee80211_vif_is_mesh(&sdata->vif))
-               hdrlen += ieee80211_get_mesh_hdrlen(
-                               (struct ieee80211s_hdr *) (skb->data + hdrlen));
-
        /* convert IEEE 802.11 header + possible LLC headers into Ethernet
         * header
         * IEEE 802.11 address fields:
@@ -1139,6 +1130,15 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
                if (unlikely(sdata->vif.type != NL80211_IFTYPE_WDS &&
                             sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
                        return -1;
+               if (ieee80211_vif_is_mesh(&sdata->vif)) {
+                       struct ieee80211s_hdr *meshdr = (struct ieee80211s_hdr *)
+                               (skb->data + hdrlen);
+                       hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
+                       if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
+                               memcpy(dst, meshdr->eaddr1, ETH_ALEN);
+                               memcpy(src, meshdr->eaddr2, ETH_ALEN);
+                       }
+               }
                break;
        case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS):
                if (sdata->vif.type != NL80211_IFTYPE_STATION ||
@@ -1379,7 +1379,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
        return RX_QUEUED;
 }
 
-static ieee80211_rx_result debug_noinline
+static ieee80211_rx_result
 ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
 {
        struct ieee80211_hdr *hdr;
@@ -1398,6 +1398,25 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
                /* illegal frame */
                return RX_DROP_MONITOR;
 
+       if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){
+               struct ieee80211_sub_if_data *sdata;
+               struct mesh_path *mppath;
+
+               sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
+               rcu_read_lock();
+               mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata);
+               if (!mppath) {
+                       mpp_path_add(mesh_hdr->eaddr2, hdr->addr4, sdata);
+               } else {
+                       spin_lock_bh(&mppath->state_lock);
+                       mppath->exp_time = jiffies;
+                       if (compare_ether_addr(mppath->mpp, hdr->addr4) != 0)
+                               memcpy(mppath->mpp, hdr->addr4, ETH_ALEN);
+                       spin_unlock_bh(&mppath->state_lock);
+               }
+               rcu_read_unlock();
+       }
+
        if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0)
                return RX_CONTINUE;
 
@@ -1538,7 +1557,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
         */
        if (sdata->vif.type != NL80211_IFTYPE_STATION &&
            sdata->vif.type != NL80211_IFTYPE_ADHOC)
-               return RX_DROP_MONITOR;
+               return RX_CONTINUE;
 
        switch (mgmt->u.action.category) {
        case WLAN_CATEGORY_BACK:
index d9774ac2e0f7c1310f4cbf5cd8c5433c1768f85c..9b72d15bc8dcb7c12978c607e057a67626c482c1 100644 (file)
@@ -93,8 +93,7 @@ static int sta_info_hash_del(struct ieee80211_local *local,
 }
 
 /* protected by RCU */
-static struct sta_info *__sta_info_find(struct ieee80211_local *local,
-                                       const u8 *addr)
+struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr)
 {
        struct sta_info *sta;
 
@@ -107,12 +106,6 @@ static struct sta_info *__sta_info_find(struct ieee80211_local *local,
        return sta;
 }
 
-struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr)
-{
-       return __sta_info_find(local, addr);
-}
-EXPORT_SYMBOL(sta_info_get);
-
 struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
                                     struct net_device *dev)
 {
@@ -146,7 +139,7 @@ static void __sta_info_free(struct ieee80211_local *local,
 {
        DECLARE_MAC_BUF(mbuf);
 
-       rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv);
+       rate_control_free_sta(sta);
        rate_control_put(sta->rate_ctrl);
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -244,7 +237,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
 
        sta->rate_ctrl = rate_control_get(local->rate_ctrl);
        sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl,
-                                                    gfp);
+                                                    &sta->sta, gfp);
        if (!sta->rate_ctrl_priv) {
                rate_control_put(sta->rate_ctrl);
                kfree(sta);
@@ -308,7 +301,7 @@ int sta_info_insert(struct sta_info *sta)
 
        spin_lock_irqsave(&local->sta_lock, flags);
        /* check if STA exists already */
-       if (__sta_info_find(local, sta->sta.addr)) {
+       if (sta_info_get(local, sta->sta.addr)) {
                spin_unlock_irqrestore(&local->sta_lock, flags);
                err = -EEXIST;
                goto out_free;
@@ -834,7 +827,7 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
 struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
                                          const u8 *addr)
 {
-       struct sta_info *sta = __sta_info_find(hw_to_local(hw), addr);
+       struct sta_info *sta = sta_info_get(hw_to_local(hw), addr);
 
        if (!sta)
                return NULL;
index daedfa9e1c63f0e0d0216ccad59fdcbfd513f6f8..a6b51862a89d2b8fc46ab9bdf7ff8fc2e27d89df 100644 (file)
@@ -189,7 +189,6 @@ struct sta_ampdu_mlme {
  * @last_qual: qual of last received frame from this STA
  * @last_noise: noise of last received frame from this STA
  * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
- * @wme_rx_queue: TBD
  * @tx_filtered_count: TBD
  * @tx_retry_failed: TBD
  * @tx_retry_count: TBD
@@ -199,7 +198,6 @@ struct sta_ampdu_mlme {
  * @tx_fragments: number of transmitted MPDUs
  * @last_txrate_idx: Index of the last used transmit rate
  * @tid_seq: TBD
- * @wme_tx_queue: TBD
  * @ampdu_mlme: TBD
  * @timer_to_tid: identity mapping to ID timers
  * @tid_to_tx_q: map tid to tx queue
@@ -258,9 +256,6 @@ struct sta_info {
        int last_qual;
        int last_noise;
        __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-       unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES];
-#endif
 
        /* Updated from TX status path only, no locking requirements */
        unsigned long tx_filtered_count;
@@ -274,9 +269,6 @@ struct sta_info {
        unsigned long tx_fragments;
        unsigned int last_txrate_idx;
        u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-       unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES];
-#endif
 
        /*
         * Aggregation information, locked with lock.
@@ -307,10 +299,6 @@ struct sta_info {
                struct dentry *num_ps_buf_frames;
                struct dentry *inactive_ms;
                struct dentry *last_seq_ctrl;
-#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
-               struct dentry *wme_rx_queue;
-               struct dentry *wme_tx_queue;
-#endif
                struct dentry *agg_status;
        } debugfs;
 #endif
@@ -416,7 +404,7 @@ static inline u32 get_sta_flags(struct sta_info *sta)
 /*
  * Get a STA info, must have be under RCU read lock.
  */
-struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr);
+struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr);
 /*
  * Get STA info by index, BROKEN!
  */
index 20d683641b4240d13af738d47a11bdbbeb2dad8c..0cc2e23f082cf5c3189420f5843aa2d65e6203f9 100644 (file)
@@ -165,11 +165,10 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
        return cpu_to_le16(dur);
 }
 
-static int inline is_ieee80211_device(struct net_device *dev,
-                                     struct net_device *master)
+static int inline is_ieee80211_device(struct ieee80211_local *local,
+                                     struct net_device *dev)
 {
-       return (wdev_priv(dev->ieee80211_ptr) ==
-               wdev_priv(master->ieee80211_ptr));
+       return local == wdev_priv(dev->ieee80211_ptr);
 }
 
 /* tx handlers */
@@ -447,7 +446,8 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
        if (likely(tx->rate_idx < 0)) {
-               rate_control_get_rate(tx->dev, sband, tx->skb, &rsel);
+               rate_control_get_rate(tx->sdata, sband, tx->sta,
+                                     tx->skb, &rsel);
                if (tx->sta)
                        tx->sta->last_txrate_idx = rsel.rate_idx;
                tx->rate_idx = rsel.rate_idx;
@@ -1001,14 +1001,14 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 /*
  * NB: @tx is uninitialised when passed in here
  */
-static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
-                               struct sk_buff *skb,
-                               struct net_device *mdev)
+static int ieee80211_tx_prepare(struct ieee80211_local *local,
+                               struct ieee80211_tx_data *tx,
+                               struct sk_buff *skb)
 {
        struct net_device *dev;
 
        dev = dev_get_by_index(&init_net, skb->iif);
-       if (unlikely(dev && !is_ieee80211_device(dev, mdev))) {
+       if (unlikely(dev && !is_ieee80211_device(local, dev))) {
                dev_put(dev);
                dev = NULL;
        }
@@ -1258,6 +1258,8 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
 int ieee80211_master_start_xmit(struct sk_buff *skb,
                                struct net_device *dev)
 {
+       struct ieee80211_master_priv *mpriv = netdev_priv(dev);
+       struct ieee80211_local *local = mpriv->local;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct net_device *odev = NULL;
@@ -1273,7 +1275,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
 
        if (skb->iif)
                odev = dev_get_by_index(&init_net, skb->iif);
-       if (unlikely(odev && !is_ieee80211_device(odev, dev))) {
+       if (unlikely(odev && !is_ieee80211_device(local, odev))) {
                dev_put(odev);
                odev = NULL;
        }
@@ -1449,8 +1451,8 @@ fail:
 int ieee80211_subif_start_xmit(struct sk_buff *skb,
                               struct net_device *dev)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_local *local = sdata->local;
        int ret = 1, head_need;
        u16 ethertype, hdrlen,  meshhdrlen = 0;
        __le16 fc;
@@ -1462,7 +1464,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
        struct sta_info *sta;
        u32 sta_flags = 0;
 
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (unlikely(skb->len < ETH_HLEN)) {
                ret = 0;
                goto fail;
@@ -1498,18 +1499,50 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 #ifdef CONFIG_MAC80211_MESH
        case NL80211_IFTYPE_MESH_POINT:
                fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
-               /* RA TA DA SA */
-               memset(hdr.addr1, 0, ETH_ALEN);
-               memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
-               memcpy(hdr.addr3, skb->data, ETH_ALEN);
-               memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
                if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
                        /* Do not send frames with mesh_ttl == 0 */
                        sdata->u.mesh.mshstats.dropped_frames_ttl++;
                        ret = 0;
                        goto fail;
                }
-               meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata);
+               memset(&mesh_hdr, 0, sizeof(mesh_hdr));
+
+               if (compare_ether_addr(dev->dev_addr,
+                                         skb->data + ETH_ALEN) == 0) {
+                       /* RA TA DA SA */
+                       memset(hdr.addr1, 0, ETH_ALEN);
+                       memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
+                       memcpy(hdr.addr3, skb->data, ETH_ALEN);
+                       memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
+                       meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata);
+               } else {
+                       /* packet from other interface */
+                       struct mesh_path *mppath;
+
+                       memset(hdr.addr1, 0, ETH_ALEN);
+                       memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
+                       memcpy(hdr.addr4, dev->dev_addr, ETH_ALEN);
+
+                       if (is_multicast_ether_addr(skb->data))
+                               memcpy(hdr.addr3, skb->data, ETH_ALEN);
+                       else {
+                               rcu_read_lock();
+                               mppath = mpp_path_lookup(skb->data, sdata);
+                               if (mppath)
+                                       memcpy(hdr.addr3, mppath->mpp, ETH_ALEN);
+                               else
+                                       memset(hdr.addr3, 0xff, ETH_ALEN);
+                               rcu_read_unlock();
+                       }
+
+                       mesh_hdr.flags |= MESH_FLAGS_AE_A5_A6;
+                       mesh_hdr.ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
+                       put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &mesh_hdr.seqnum);
+                       memcpy(mesh_hdr.eaddr1, skb->data, ETH_ALEN);
+                       memcpy(mesh_hdr.eaddr2, skb->data + ETH_ALEN, ETH_ALEN);
+                       sdata->u.mesh.mesh_seqnum++;
+                       meshhdrlen = 18;
+               }
                hdrlen = 30;
                break;
 #endif
@@ -1923,7 +1956,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
        skb->do_not_encrypt = 1;
 
        info->band = band;
-       rate_control_get_rate(local->mdev, sband, skb, &rsel);
+       rate_control_get_rate(sdata, sband, NULL, skb, &rsel);
 
        if (unlikely(rsel.rate_idx < 0)) {
                if (net_ratelimit()) {
@@ -2032,7 +2065,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
                                cpu_to_le16(IEEE80211_FCTL_MOREDATA);
                }
 
-               if (!ieee80211_tx_prepare(&tx, skb, local->mdev))
+               if (!ieee80211_tx_prepare(local, &tx, skb))
                        break;
                dev_kfree_skb_any(skb);
        }
index c703f8b44e92735214056c548a8495dab5c0ca7d..139b5f267b34b4e38d2925996936ab7f389061a9 100644 (file)
@@ -73,9 +73,8 @@ static int wme_downgrade_ac(struct sk_buff *skb)
 
 
 /* Indicate which queue to use.  */
-static u16 classify80211(struct sk_buff *skb, struct net_device *dev)
+static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 
        if (!ieee80211_is_data(hdr->frame_control)) {
@@ -113,14 +112,15 @@ static u16 classify80211(struct sk_buff *skb, struct net_device *dev)
 
 u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
+       struct ieee80211_master_priv *mpriv = netdev_priv(dev);
+       struct ieee80211_local *local = mpriv->local;
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct sta_info *sta;
        u16 queue;
        u8 tid;
 
-       queue = classify80211(skb, dev);
+       queue = classify80211(local, skb);
        if (unlikely(queue >= local->hw.queues))
                queue = local->hw.queues - 1;
 
index 9f328593287eabfcaf8c13e013fbc5458e61da89..307a2c3c2df45caf9ec84dd1e2af302030e55808 100644 (file)
@@ -136,17 +136,19 @@ static void localtime_3(struct xtm *r, time_t time)
         * from w repeatedly while counting.)
         */
        if (is_leap(year)) {
+               /* use days_since_leapyear[] in a leap year */
                for (i = ARRAY_SIZE(days_since_leapyear) - 1;
-                   i > 0 && days_since_year[i] > w; --i)
+                   i > 0 && days_since_leapyear[i] > w; --i)
                        /* just loop */;
+               r->monthday = w - days_since_leapyear[i] + 1;
        } else {
                for (i = ARRAY_SIZE(days_since_year) - 1;
                    i > 0 && days_since_year[i] > w; --i)
                        /* just loop */;
+               r->monthday = w - days_since_year[i] + 1;
        }
 
        r->month    = i + 1;
-       r->monthday = w - days_since_year[i] + 1;
        return;
 }
 
diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig
new file mode 100644 (file)
index 0000000..51a5669
--- /dev/null
@@ -0,0 +1,16 @@
+#
+# Phonet protocol
+#
+
+config PHONET
+       tristate "Phonet protocols family"
+       help
+         The Phone Network protocol (PhoNet) is a packet-oriented
+         communication protocol developped by Nokia for use with its modems.
+
+         This is required for Maemo to use cellular data connectivity (if
+         supported). It can also be used to control Nokia phones
+         from a Linux computer, although AT commands may be easier to use.
+
+         To compile this driver as a module, choose M here: the module
+         will be called phonet. If unsure, say N.
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
new file mode 100644 (file)
index 0000000..d62bbba
--- /dev/null
@@ -0,0 +1,11 @@
+obj-$(CONFIG_PHONET) += phonet.o pn_pep.o
+
+phonet-objs := \
+       pn_dev.o \
+       pn_netlink.o \
+       socket.o \
+       datagram.o \
+       sysctl.o \
+       af_phonet.o
+
+pn_pep-objs := pep.o pep-gprs.o
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
new file mode 100644 (file)
index 0000000..9e9c6fc
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * File: af_phonet.c
+ *
+ * Phonet protocols family
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+ * Original author: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <asm/unaligned.h>
+#include <net/sock.h>
+
+#include <linux/if_phonet.h>
+#include <linux/phonet.h>
+#include <net/phonet/phonet.h>
+#include <net/phonet/pn_dev.h>
+
+static struct net_proto_family phonet_proto_family;
+static struct phonet_protocol *phonet_proto_get(int protocol);
+static inline void phonet_proto_put(struct phonet_protocol *pp);
+
+/* protocol family functions */
+
+static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
+{
+       struct sock *sk;
+       struct pn_sock *pn;
+       struct phonet_protocol *pnp;
+       int err;
+
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       if (protocol == 0) {
+               /* Default protocol selection */
+               switch (sock->type) {
+               case SOCK_DGRAM:
+                       protocol = PN_PROTO_PHONET;
+                       break;
+               case SOCK_SEQPACKET:
+                       protocol = PN_PROTO_PIPE;
+                       break;
+               default:
+                       return -EPROTONOSUPPORT;
+               }
+       }
+
+       pnp = phonet_proto_get(protocol);
+#ifdef CONFIG_KMOD
+       if (pnp == NULL &&
+           request_module("net-pf-%d-proto-%d", PF_PHONET, protocol) == 0)
+               pnp = phonet_proto_get(protocol);
+#endif
+       if (pnp == NULL)
+               return -EPROTONOSUPPORT;
+       if (sock->type != pnp->sock_type) {
+               err = -EPROTONOSUPPORT;
+               goto out;
+       }
+
+       sk = sk_alloc(net, PF_PHONET, GFP_KERNEL, pnp->prot);
+       if (sk == NULL) {
+               err = -ENOMEM;
+               goto out;
+       }
+
+       sock_init_data(sock, sk);
+       sock->state = SS_UNCONNECTED;
+       sock->ops = pnp->ops;
+       sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
+       sk->sk_protocol = protocol;
+       pn = pn_sk(sk);
+       pn->sobject = 0;
+       pn->resource = 0;
+       sk->sk_prot->init(sk);
+       err = 0;
+
+out:
+       phonet_proto_put(pnp);
+       return err;
+}
+
+static struct net_proto_family phonet_proto_family = {
+       .family = PF_PHONET,
+       .create = pn_socket_create,
+       .owner = THIS_MODULE,
+};
+
+/* Phonet device header operations */
+static int pn_header_create(struct sk_buff *skb, struct net_device *dev,
+                               unsigned short type, const void *daddr,
+                               const void *saddr, unsigned len)
+{
+       u8 *media = skb_push(skb, 1);
+
+       if (type != ETH_P_PHONET)
+               return -1;
+
+       if (!saddr)
+               saddr = dev->dev_addr;
+       *media = *(const u8 *)saddr;
+       return 1;
+}
+
+static int pn_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+{
+       const u8 *media = skb_mac_header(skb);
+       *haddr = *media;
+       return 1;
+}
+
+struct header_ops phonet_header_ops = {
+       .create = pn_header_create,
+       .parse = pn_header_parse,
+};
+EXPORT_SYMBOL(phonet_header_ops);
+
+/*
+ * Prepends an ISI header and sends a datagram.
+ */
+static int pn_send(struct sk_buff *skb, struct net_device *dev,
+                       u16 dst, u16 src, u8 res, u8 irq)
+{
+       struct phonethdr *ph;
+       int err;
+
+       if (skb->len + 2 > 0xffff) {
+               /* Phonet length field would overflow */
+               err = -EMSGSIZE;
+               goto drop;
+       }
+
+       skb_reset_transport_header(skb);
+       WARN_ON(skb_headroom(skb) & 1); /* HW assumes word alignment */
+       skb_push(skb, sizeof(struct phonethdr));
+       skb_reset_network_header(skb);
+       ph = pn_hdr(skb);
+       ph->pn_rdev = pn_dev(dst);
+       ph->pn_sdev = pn_dev(src);
+       ph->pn_res = res;
+       ph->pn_length = __cpu_to_be16(skb->len + 2 - sizeof(*ph));
+       ph->pn_robj = pn_obj(dst);
+       ph->pn_sobj = pn_obj(src);
+
+       skb->protocol = htons(ETH_P_PHONET);
+       skb->priority = 0;
+       skb->dev = dev;
+
+       if (pn_addr(src) == pn_addr(dst)) {
+               skb_reset_mac_header(skb);
+               skb->pkt_type = PACKET_LOOPBACK;
+               skb_orphan(skb);
+               if (irq)
+                       netif_rx(skb);
+               else
+                       netif_rx_ni(skb);
+               err = 0;
+       } else {
+               err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+                                       NULL, NULL, skb->len);
+               if (err < 0) {
+                       err = -EHOSTUNREACH;
+                       goto drop;
+               }
+               err = dev_queue_xmit(skb);
+       }
+
+       return err;
+drop:
+       kfree_skb(skb);
+       return err;
+}
+
+static int pn_raw_send(const void *data, int len, struct net_device *dev,
+                       u16 dst, u16 src, u8 res)
+{
+       struct sk_buff *skb = alloc_skb(MAX_PHONET_HEADER + len, GFP_ATOMIC);
+       if (skb == NULL)
+               return -ENOMEM;
+
+       skb_reserve(skb, MAX_PHONET_HEADER);
+       __skb_put(skb, len);
+       skb_copy_to_linear_data(skb, data, len);
+       return pn_send(skb, dev, dst, src, res, 1);
+}
+
+/*
+ * Create a Phonet header for the skb and send it out. Returns
+ * non-zero error code if failed. The skb is freed then.
+ */
+int pn_skb_send(struct sock *sk, struct sk_buff *skb,
+               const struct sockaddr_pn *target)
+{
+       struct net_device *dev;
+       struct pn_sock *pn = pn_sk(sk);
+       int err;
+       u16 src;
+       u8 daddr = pn_sockaddr_get_addr(target), saddr = PN_NO_ADDR;
+
+       err = -EHOSTUNREACH;
+       if (sk->sk_bound_dev_if)
+               dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if);
+       else
+               dev = phonet_device_get(sock_net(sk));
+       if (!dev || !(dev->flags & IFF_UP))
+               goto drop;
+
+       saddr = phonet_address_get(dev, daddr);
+       if (saddr == PN_NO_ADDR)
+               goto drop;
+
+       src = pn->sobject;
+       if (!pn_addr(src))
+               src = pn_object(saddr, pn_obj(src));
+
+       err = pn_send(skb, dev, pn_sockaddr_get_object(target),
+                       src, pn_sockaddr_get_resource(target), 0);
+       dev_put(dev);
+       return err;
+
+drop:
+       kfree_skb(skb);
+       if (dev)
+               dev_put(dev);
+       return err;
+}
+EXPORT_SYMBOL(pn_skb_send);
+
+/* Do not send an error message in response to an error message */
+static inline int can_respond(struct sk_buff *skb)
+{
+       const struct phonethdr *ph;
+       const struct phonetmsg *pm;
+       u8 submsg_id;
+
+       if (!pskb_may_pull(skb, 3))
+               return 0;
+
+       ph = pn_hdr(skb);
+       if (phonet_address_get(skb->dev, ph->pn_rdev) != ph->pn_rdev)
+               return 0; /* we are not the destination */
+       if (ph->pn_res == PN_PREFIX && !pskb_may_pull(skb, 5))
+               return 0;
+
+       ph = pn_hdr(skb); /* re-acquires the pointer */
+       pm = pn_msg(skb);
+       if (pm->pn_msg_id != PN_COMMON_MESSAGE)
+               return 1;
+       submsg_id = (ph->pn_res == PN_PREFIX)
+               ? pm->pn_e_submsg_id : pm->pn_submsg_id;
+       if (submsg_id != PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP &&
+               pm->pn_e_submsg_id != PN_COMM_SERVICE_NOT_IDENTIFIED_RESP)
+               return 1;
+       return 0;
+}
+
+static int send_obj_unreachable(struct sk_buff *rskb)
+{
+       const struct phonethdr *oph = pn_hdr(rskb);
+       const struct phonetmsg *opm = pn_msg(rskb);
+       struct phonetmsg resp;
+
+       memset(&resp, 0, sizeof(resp));
+       resp.pn_trans_id = opm->pn_trans_id;
+       resp.pn_msg_id = PN_COMMON_MESSAGE;
+       if (oph->pn_res == PN_PREFIX) {
+               resp.pn_e_res_id = opm->pn_e_res_id;
+               resp.pn_e_submsg_id = PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP;
+               resp.pn_e_orig_msg_id = opm->pn_msg_id;
+               resp.pn_e_status = 0;
+       } else {
+               resp.pn_submsg_id = PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP;
+               resp.pn_orig_msg_id = opm->pn_msg_id;
+               resp.pn_status = 0;
+       }
+       return pn_raw_send(&resp, sizeof(resp), rskb->dev,
+                               pn_object(oph->pn_sdev, oph->pn_sobj),
+                               pn_object(oph->pn_rdev, oph->pn_robj),
+                               oph->pn_res);
+}
+
+static int send_reset_indications(struct sk_buff *rskb)
+{
+       struct phonethdr *oph = pn_hdr(rskb);
+       static const u8 data[4] = {
+               0x00 /* trans ID */, 0x10 /* subscribe msg */,
+               0x00 /* subscription count */, 0x00 /* dummy */
+       };
+
+       return pn_raw_send(data, sizeof(data), rskb->dev,
+                               pn_object(oph->pn_sdev, 0x00),
+                               pn_object(oph->pn_rdev, oph->pn_robj), 0x10);
+}
+
+
+/* packet type functions */
+
+/*
+ * Stuff received packets to associated sockets.
+ * On error, returns non-zero and releases the skb.
+ */
+static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
+                       struct packet_type *pkttype,
+                       struct net_device *orig_dev)
+{
+       struct phonethdr *ph;
+       struct sock *sk;
+       struct sockaddr_pn sa;
+       u16 len;
+
+       if (dev_net(dev) != &init_net)
+               goto out;
+
+       /* check we have at least a full Phonet header */
+       if (!pskb_pull(skb, sizeof(struct phonethdr)))
+               goto out;
+
+       /* check that the advertised length is correct */
+       ph = pn_hdr(skb);
+       len = get_unaligned_be16(&ph->pn_length);
+       if (len < 2)
+               goto out;
+       len -= 2;
+       if ((len > skb->len) || pskb_trim(skb, len))
+               goto out;
+       skb_reset_transport_header(skb);
+
+       pn_skb_get_dst_sockaddr(skb, &sa);
+       if (pn_sockaddr_get_addr(&sa) == 0)
+               goto out; /* currently, we cannot be device 0 */
+
+       sk = pn_find_sock_by_sa(&sa);
+       if (sk == NULL) {
+               if (can_respond(skb)) {
+                       send_obj_unreachable(skb);
+                       send_reset_indications(skb);
+               }
+               goto out;
+       }
+
+       /* Push data to the socket (or other sockets connected to it). */
+       return sk_receive_skb(sk, skb, 0);
+
+out:
+       kfree_skb(skb);
+       return NET_RX_DROP;
+}
+
+static struct packet_type phonet_packet_type = {
+       .type = __constant_htons(ETH_P_PHONET),
+       .dev = NULL,
+       .func = phonet_rcv,
+};
+
+/* Transport protocol registration */
+static struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly;
+static DEFINE_SPINLOCK(proto_tab_lock);
+
+int __init_or_module phonet_proto_register(int protocol,
+                                               struct phonet_protocol *pp)
+{
+       int err = 0;
+
+       if (protocol >= PHONET_NPROTO)
+               return -EINVAL;
+
+       err = proto_register(pp->prot, 1);
+       if (err)
+               return err;
+
+       spin_lock(&proto_tab_lock);
+       if (proto_tab[protocol])
+               err = -EBUSY;
+       else
+               proto_tab[protocol] = pp;
+       spin_unlock(&proto_tab_lock);
+
+       return err;
+}
+EXPORT_SYMBOL(phonet_proto_register);
+
+void phonet_proto_unregister(int protocol, struct phonet_protocol *pp)
+{
+       spin_lock(&proto_tab_lock);
+       BUG_ON(proto_tab[protocol] != pp);
+       proto_tab[protocol] = NULL;
+       spin_unlock(&proto_tab_lock);
+       proto_unregister(pp->prot);
+}
+EXPORT_SYMBOL(phonet_proto_unregister);
+
+static struct phonet_protocol *phonet_proto_get(int protocol)
+{
+       struct phonet_protocol *pp;
+
+       if (protocol >= PHONET_NPROTO)
+               return NULL;
+
+       spin_lock(&proto_tab_lock);
+       pp = proto_tab[protocol];
+       if (pp && !try_module_get(pp->prot->owner))
+               pp = NULL;
+       spin_unlock(&proto_tab_lock);
+
+       return pp;
+}
+
+static inline void phonet_proto_put(struct phonet_protocol *pp)
+{
+       module_put(pp->prot->owner);
+}
+
+/* Module registration */
+static int __init phonet_init(void)
+{
+       int err;
+
+       err = sock_register(&phonet_proto_family);
+       if (err) {
+               printk(KERN_ALERT
+                       "phonet protocol family initialization failed\n");
+               return err;
+       }
+
+       phonet_device_init();
+       dev_add_pack(&phonet_packet_type);
+       phonet_netlink_register();
+       phonet_sysctl_init();
+
+       err = isi_register();
+       if (err)
+               goto err;
+       return 0;
+
+err:
+       phonet_sysctl_exit();
+       sock_unregister(PF_PHONET);
+       dev_remove_pack(&phonet_packet_type);
+       phonet_device_exit();
+       return err;
+}
+
+static void __exit phonet_exit(void)
+{
+       isi_unregister();
+       phonet_sysctl_exit();
+       sock_unregister(PF_PHONET);
+       dev_remove_pack(&phonet_packet_type);
+       phonet_device_exit();
+}
+
+module_init(phonet_init);
+module_exit(phonet_exit);
+MODULE_DESCRIPTION("Phonet protocol stack for Linux");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_NETPROTO(PF_PHONET);
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
new file mode 100644 (file)
index 0000000..e087862
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * File: datagram.c
+ *
+ * Datagram (ISI) Phonet sockets
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+ * Original author: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/socket.h>
+#include <asm/ioctls.h>
+#include <net/sock.h>
+
+#include <linux/phonet.h>
+#include <net/phonet/phonet.h>
+
+static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb);
+
+/* associated socket ceases to exist */
+static void pn_sock_close(struct sock *sk, long timeout)
+{
+       sk_common_release(sk);
+}
+
+static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg)
+{
+       struct sk_buff *skb;
+       int answ;
+
+       switch (cmd) {
+       case SIOCINQ:
+               lock_sock(sk);
+               skb = skb_peek(&sk->sk_receive_queue);
+               answ = skb ? skb->len : 0;
+               release_sock(sk);
+               return put_user(answ, (int __user *)arg);
+       }
+
+       return -ENOIOCTLCMD;
+}
+
+/* Destroy socket. All references are gone. */
+static void pn_destruct(struct sock *sk)
+{
+       skb_queue_purge(&sk->sk_receive_queue);
+}
+
+static int pn_init(struct sock *sk)
+{
+       sk->sk_destruct = pn_destruct;
+       return 0;
+}
+
+static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,
+                       struct msghdr *msg, size_t len)
+{
+       struct sockaddr_pn *target;
+       struct sk_buff *skb;
+       int err;
+
+       if (msg->msg_flags & MSG_OOB)
+               return -EOPNOTSUPP;
+
+       if (msg->msg_name == NULL)
+               return -EDESTADDRREQ;
+
+       if (msg->msg_namelen < sizeof(struct sockaddr_pn))
+               return -EINVAL;
+
+       target = (struct sockaddr_pn *)msg->msg_name;
+       if (target->spn_family != AF_PHONET)
+               return -EAFNOSUPPORT;
+
+       skb = sock_alloc_send_skb(sk, MAX_PHONET_HEADER + len,
+                                       msg->msg_flags & MSG_DONTWAIT, &err);
+       if (skb == NULL)
+               return err;
+       skb_reserve(skb, MAX_PHONET_HEADER);
+
+       err = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len);
+       if (err < 0) {
+               kfree_skb(skb);
+               return err;
+       }
+
+       /*
+        * Fill in the Phonet header and
+        * finally pass the packet forwards.
+        */
+       err = pn_skb_send(sk, skb, target);
+
+       /* If ok, return len. */
+       return (err >= 0) ? len : err;
+}
+
+static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
+                       struct msghdr *msg, size_t len, int noblock,
+                       int flags, int *addr_len)
+{
+       struct sk_buff *skb = NULL;
+       struct sockaddr_pn sa;
+       int rval = -EOPNOTSUPP;
+       int copylen;
+
+       if (flags & MSG_OOB)
+               goto out_nofree;
+
+       if (addr_len)
+               *addr_len = sizeof(sa);
+
+       skb = skb_recv_datagram(sk, flags, noblock, &rval);
+       if (skb == NULL)
+               goto out_nofree;
+
+       pn_skb_get_src_sockaddr(skb, &sa);
+
+       copylen = skb->len;
+       if (len < copylen) {
+               msg->msg_flags |= MSG_TRUNC;
+               copylen = len;
+       }
+
+       rval = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copylen);
+       if (rval) {
+               rval = -EFAULT;
+               goto out;
+       }
+
+       rval = (flags & MSG_TRUNC) ? skb->len : copylen;
+
+       if (msg->msg_name != NULL)
+               memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));
+
+out:
+       skb_free_datagram(sk, skb);
+
+out_nofree:
+       return rval;
+}
+
+/* Queue an skb for a sock. */
+static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb)
+{
+       int err = sock_queue_rcv_skb(sk, skb);
+       if (err < 0)
+               kfree_skb(skb);
+       return err ? NET_RX_DROP : NET_RX_SUCCESS;
+}
+
+/* Module registration */
+static struct proto pn_proto = {
+       .close          = pn_sock_close,
+       .ioctl          = pn_ioctl,
+       .init           = pn_init,
+       .sendmsg        = pn_sendmsg,
+       .recvmsg        = pn_recvmsg,
+       .backlog_rcv    = pn_backlog_rcv,
+       .hash           = pn_sock_hash,
+       .unhash         = pn_sock_unhash,
+       .get_port       = pn_sock_get_port,
+       .obj_size       = sizeof(struct pn_sock),
+       .owner          = THIS_MODULE,
+       .name           = "PHONET",
+};
+
+static struct phonet_protocol pn_dgram_proto = {
+       .ops            = &phonet_dgram_ops,
+       .prot           = &pn_proto,
+       .sock_type      = SOCK_DGRAM,
+};
+
+int __init isi_register(void)
+{
+       return phonet_proto_register(PN_PROTO_PHONET, &pn_dgram_proto);
+}
+
+void __exit isi_unregister(void)
+{
+       phonet_proto_unregister(PN_PROTO_PHONET, &pn_dgram_proto);
+}
diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c
new file mode 100644 (file)
index 0000000..9978afb
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * File: pep-gprs.c
+ *
+ * GPRS over Phonet pipe end point socket
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <net/sock.h>
+
+#include <linux/if_phonet.h>
+#include <net/tcp_states.h>
+#include <net/phonet/gprs.h>
+
+#define GPRS_DEFAULT_MTU 1400
+
+struct gprs_dev {
+       struct sock             *sk;
+       void                    (*old_state_change)(struct sock *);
+       void                    (*old_data_ready)(struct sock *, int);
+       void                    (*old_write_space)(struct sock *);
+
+       struct net_device       *net;
+       struct net_device_stats stats;
+
+       struct sk_buff_head     tx_queue;
+       struct work_struct      tx_work;
+       spinlock_t              tx_lock;
+       unsigned                tx_max;
+};
+
+static int gprs_type_trans(struct sk_buff *skb)
+{
+       const u8 *pvfc;
+       u8 buf;
+
+       pvfc = skb_header_pointer(skb, 0, 1, &buf);
+       if (!pvfc)
+               return 0;
+       /* Look at IP version field */
+       switch (*pvfc >> 4) {
+       case 4:
+               return htons(ETH_P_IP);
+       case 6:
+               return htons(ETH_P_IPV6);
+       }
+       return 0;
+}
+
+/*
+ * Socket callbacks
+ */
+
+static void gprs_state_change(struct sock *sk)
+{
+       struct gprs_dev *dev = sk->sk_user_data;
+
+       if (sk->sk_state == TCP_CLOSE_WAIT) {
+               netif_stop_queue(dev->net);
+               netif_carrier_off(dev->net);
+       }
+}
+
+static int gprs_recv(struct gprs_dev *dev, struct sk_buff *skb)
+{
+       int err = 0;
+       u16 protocol = gprs_type_trans(skb);
+
+       if (!protocol) {
+               err = -EINVAL;
+               goto drop;
+       }
+
+       if (likely(skb_headroom(skb) & 3)) {
+               struct sk_buff *rskb, *fs;
+               int flen = 0;
+
+               /* Phonet Pipe data header is misaligned (3 bytes),
+                * so wrap the IP packet as a single fragment of an head-less
+                * socket buffer. The network stack will pull what it needs,
+                * but at least, the whole IP payload is not memcpy'd. */
+               rskb = netdev_alloc_skb(dev->net, 0);
+               if (!rskb) {
+                       err = -ENOBUFS;
+                       goto drop;
+               }
+               skb_shinfo(rskb)->frag_list = skb;
+               rskb->len += skb->len;
+               rskb->data_len += rskb->len;
+               rskb->truesize += rskb->len;
+
+               /* Avoid nested fragments */
+               for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
+                       flen += fs->len;
+               skb->next = skb_shinfo(skb)->frag_list;
+               skb_shinfo(skb)->frag_list = NULL;
+               skb->len -= flen;
+               skb->data_len -= flen;
+               skb->truesize -= flen;
+
+               skb = rskb;
+       }
+
+       skb->protocol = protocol;
+       skb_reset_mac_header(skb);
+       skb->dev = dev->net;
+
+       if (likely(dev->net->flags & IFF_UP)) {
+               dev->stats.rx_packets++;
+               dev->stats.rx_bytes += skb->len;
+               netif_rx(skb);
+               skb = NULL;
+       } else
+               err = -ENODEV;
+
+drop:
+       if (skb) {
+               dev_kfree_skb(skb);
+               dev->stats.rx_dropped++;
+       }
+       return err;
+}
+
+static void gprs_data_ready(struct sock *sk, int len)
+{
+       struct gprs_dev *dev = sk->sk_user_data;
+       struct sk_buff *skb;
+
+       while ((skb = pep_read(sk)) != NULL) {
+               skb_orphan(skb);
+               gprs_recv(dev, skb);
+       }
+}
+
+static void gprs_write_space(struct sock *sk)
+{
+       struct gprs_dev *dev = sk->sk_user_data;
+       unsigned credits = pep_writeable(sk);
+
+       spin_lock_bh(&dev->tx_lock);
+       dev->tx_max = credits;
+       if (credits > skb_queue_len(&dev->tx_queue))
+               netif_wake_queue(dev->net);
+       spin_unlock_bh(&dev->tx_lock);
+}
+
+/*
+ * Network device callbacks
+ */
+
+static int gprs_xmit(struct sk_buff *skb, struct net_device *net)
+{
+       struct gprs_dev *dev = netdev_priv(net);
+
+       switch (skb->protocol) {
+       case  htons(ETH_P_IP):
+       case  htons(ETH_P_IPV6):
+               break;
+       default:
+               dev_kfree_skb(skb);
+               return 0;
+       }
+
+       spin_lock(&dev->tx_lock);
+       if (likely(skb_queue_len(&dev->tx_queue) < dev->tx_max)) {
+               skb_queue_tail(&dev->tx_queue, skb);
+               skb = NULL;
+       }
+       if (skb_queue_len(&dev->tx_queue) >= dev->tx_max)
+               netif_stop_queue(net);
+       spin_unlock(&dev->tx_lock);
+
+       schedule_work(&dev->tx_work);
+       if (unlikely(skb))
+               dev_kfree_skb(skb);
+       return 0;
+}
+
+static void gprs_tx(struct work_struct *work)
+{
+       struct gprs_dev *dev = container_of(work, struct gprs_dev, tx_work);
+       struct sock *sk = dev->sk;
+       struct sk_buff *skb;
+
+       while ((skb = skb_dequeue(&dev->tx_queue)) != NULL) {
+               int err;
+
+               dev->stats.tx_bytes += skb->len;
+               dev->stats.tx_packets++;
+
+               skb_orphan(skb);
+               skb_set_owner_w(skb, sk);
+
+               lock_sock(sk);
+               err = pep_write(sk, skb);
+               if (err) {
+                       LIMIT_NETDEBUG(KERN_WARNING"%s: TX error (%d)\n",
+                                       dev->net->name, err);
+                       dev->stats.tx_aborted_errors++;
+                       dev->stats.tx_errors++;
+               }
+               release_sock(sk);
+       }
+
+       lock_sock(sk);
+       gprs_write_space(sk);
+       release_sock(sk);
+}
+
+static int gprs_set_mtu(struct net_device *net, int new_mtu)
+{
+       if ((new_mtu < 576) || (new_mtu > (PHONET_MAX_MTU - 11)))
+               return -EINVAL;
+
+       net->mtu = new_mtu;
+       return 0;
+}
+
+static struct net_device_stats *gprs_get_stats(struct net_device *net)
+{
+       struct gprs_dev *dev = netdev_priv(net);
+
+       return &dev->stats;
+}
+
+static void gprs_setup(struct net_device *net)
+{
+       net->features           = NETIF_F_FRAGLIST;
+       net->type               = ARPHRD_NONE;
+       net->flags              = IFF_POINTOPOINT | IFF_NOARP;
+       net->mtu                = GPRS_DEFAULT_MTU;
+       net->hard_header_len    = 0;
+       net->addr_len           = 0;
+       net->tx_queue_len       = 10;
+
+       net->destructor         = free_netdev;
+       net->hard_start_xmit    = gprs_xmit; /* mandatory */
+       net->change_mtu         = gprs_set_mtu;
+       net->get_stats          = gprs_get_stats;
+}
+
+/*
+ * External interface
+ */
+
+/*
+ * Attach a GPRS interface to a datagram socket.
+ * Returns the interface index on success, negative error code on error.
+ */
+int gprs_attach(struct sock *sk)
+{
+       static const char ifname[] = "gprs%d";
+       struct gprs_dev *dev;
+       struct net_device *net;
+       int err;
+
+       if (unlikely(sk->sk_type == SOCK_STREAM))
+               return -EINVAL; /* need packet boundaries */
+
+       /* Create net device */
+       net = alloc_netdev(sizeof(*dev), ifname, gprs_setup);
+       if (!net)
+               return -ENOMEM;
+       dev = netdev_priv(net);
+       dev->net = net;
+       dev->tx_max = 0;
+       spin_lock_init(&dev->tx_lock);
+       skb_queue_head_init(&dev->tx_queue);
+       INIT_WORK(&dev->tx_work, gprs_tx);
+
+       netif_stop_queue(net);
+       err = register_netdev(net);
+       if (err) {
+               free_netdev(net);
+               return err;
+       }
+
+       lock_sock(sk);
+       if (unlikely(sk->sk_user_data)) {
+               err = -EBUSY;
+               goto out_rel;
+       }
+       if (unlikely((1 << sk->sk_state & (TCPF_CLOSE|TCPF_LISTEN)) ||
+                       sock_flag(sk, SOCK_DEAD))) {
+               err = -EINVAL;
+               goto out_rel;
+       }
+       sk->sk_user_data        = dev;
+       dev->old_state_change   = sk->sk_state_change;
+       dev->old_data_ready     = sk->sk_data_ready;
+       dev->old_write_space    = sk->sk_write_space;
+       sk->sk_state_change     = gprs_state_change;
+       sk->sk_data_ready       = gprs_data_ready;
+       sk->sk_write_space      = gprs_write_space;
+       release_sock(sk);
+
+       sock_hold(sk);
+       dev->sk = sk;
+
+       printk(KERN_DEBUG"%s: attached\n", net->name);
+       gprs_write_space(sk); /* kick off TX */
+       return net->ifindex;
+
+out_rel:
+       release_sock(sk);
+       unregister_netdev(net);
+       return err;
+}
+
+void gprs_detach(struct sock *sk)
+{
+       struct gprs_dev *dev = sk->sk_user_data;
+       struct net_device *net = dev->net;
+
+       lock_sock(sk);
+       sk->sk_user_data        = NULL;
+       sk->sk_state_change     = dev->old_state_change;
+       sk->sk_data_ready       = dev->old_data_ready;
+       sk->sk_write_space      = dev->old_write_space;
+       release_sock(sk);
+
+       printk(KERN_DEBUG"%s: detached\n", net->name);
+       unregister_netdev(net);
+       flush_scheduled_work();
+       sock_put(sk);
+       skb_queue_purge(&dev->tx_queue);
+}
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
new file mode 100644 (file)
index 0000000..bc6d50f
--- /dev/null
@@ -0,0 +1,1076 @@
+/*
+ * File: pep.c
+ *
+ * Phonet pipe protocol end point socket
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/socket.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <asm/ioctls.h>
+
+#include <linux/phonet.h>
+#include <net/phonet/phonet.h>
+#include <net/phonet/pep.h>
+#include <net/phonet/gprs.h>
+
+/* sk_state values:
+ * TCP_CLOSE           sock not in use yet
+ * TCP_CLOSE_WAIT      disconnected pipe
+ * TCP_LISTEN          listening pipe endpoint
+ * TCP_SYN_RECV                connected pipe in disabled state
+ * TCP_ESTABLISHED     connected pipe in enabled state
+ *
+ * pep_sock locking:
+ *  - sk_state, ackq, hlist: sock lock needed
+ *  - listener: read only
+ *  - pipe_handle: read only
+ */
+
+#define CREDITS_MAX    10
+#define CREDITS_THR    7
+
+static const struct sockaddr_pn pipe_srv = {
+       .spn_family = AF_PHONET,
+       .spn_resource = 0xD9, /* pipe service */
+};
+
+#define pep_sb_size(s) (((s) + 5) & ~3) /* 2-bytes head, 32-bits aligned */
+
+/* Get the next TLV sub-block. */
+static unsigned char *pep_get_sb(struct sk_buff *skb, u8 *ptype, u8 *plen,
+                                       void *buf)
+{
+       void *data = NULL;
+       struct {
+               u8 sb_type;
+               u8 sb_len;
+       } *ph, h;
+       int buflen = *plen;
+
+       ph = skb_header_pointer(skb, 0, 2, &h);
+       if (ph == NULL || ph->sb_len < 2 || !pskb_may_pull(skb, ph->sb_len))
+               return NULL;
+       ph->sb_len -= 2;
+       *ptype = ph->sb_type;
+       *plen = ph->sb_len;
+
+       if (buflen > ph->sb_len)
+               buflen = ph->sb_len;
+       data = skb_header_pointer(skb, 2, buflen, buf);
+       __skb_pull(skb, 2 + ph->sb_len);
+       return data;
+}
+
+static int pep_reply(struct sock *sk, struct sk_buff *oskb,
+                       u8 code, const void *data, int len, gfp_t priority)
+{
+       const struct pnpipehdr *oph = pnp_hdr(oskb);
+       struct pnpipehdr *ph;
+       struct sk_buff *skb;
+
+       skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority);
+       if (!skb)
+               return -ENOMEM;
+       skb_set_owner_w(skb, sk);
+
+       skb_reserve(skb, MAX_PNPIPE_HEADER);
+       __skb_put(skb, len);
+       skb_copy_to_linear_data(skb, data, len);
+       __skb_push(skb, sizeof(*ph));
+       skb_reset_transport_header(skb);
+       ph = pnp_hdr(skb);
+       ph->utid = oph->utid;
+       ph->message_id = oph->message_id + 1; /* REQ -> RESP */
+       ph->pipe_handle = oph->pipe_handle;
+       ph->error_code = code;
+
+       return pn_skb_send(sk, skb, &pipe_srv);
+}
+
+#define PAD 0x00
+static int pep_accept_conn(struct sock *sk, struct sk_buff *skb)
+{
+       static const u8 data[20] = {
+               PAD, PAD, PAD, 2 /* sub-blocks */,
+               PN_PIPE_SB_REQUIRED_FC_TX, pep_sb_size(5), 3, PAD,
+                       PN_MULTI_CREDIT_FLOW_CONTROL,
+                       PN_ONE_CREDIT_FLOW_CONTROL,
+                       PN_LEGACY_FLOW_CONTROL,
+                       PAD,
+               PN_PIPE_SB_PREFERRED_FC_RX, pep_sb_size(5), 3, PAD,
+                       PN_MULTI_CREDIT_FLOW_CONTROL,
+                       PN_ONE_CREDIT_FLOW_CONTROL,
+                       PN_LEGACY_FLOW_CONTROL,
+                       PAD,
+       };
+
+       might_sleep();
+       return pep_reply(sk, skb, PN_PIPE_NO_ERROR, data, sizeof(data),
+                               GFP_KERNEL);
+}
+
+static int pep_reject_conn(struct sock *sk, struct sk_buff *skb, u8 code)
+{
+       static const u8 data[4] = { PAD, PAD, PAD, 0 /* sub-blocks */ };
+       WARN_ON(code == PN_PIPE_NO_ERROR);
+       return pep_reply(sk, skb, code, data, sizeof(data), GFP_ATOMIC);
+}
+
+/* Control requests are not sent by the pipe service and have a specific
+ * message format. */
+static int pep_ctrlreq_error(struct sock *sk, struct sk_buff *oskb, u8 code,
+                               gfp_t priority)
+{
+       const struct pnpipehdr *oph = pnp_hdr(oskb);
+       struct sk_buff *skb;
+       struct pnpipehdr *ph;
+       struct sockaddr_pn dst;
+
+       skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority);
+       if (!skb)
+               return -ENOMEM;
+       skb_set_owner_w(skb, sk);
+
+       skb_reserve(skb, MAX_PHONET_HEADER);
+       ph = (struct pnpipehdr *)skb_put(skb, sizeof(*ph) + 4);
+
+       ph->utid = oph->utid;
+       ph->message_id = PNS_PEP_CTRL_RESP;
+       ph->pipe_handle = oph->pipe_handle;
+       ph->data[0] = oph->data[1]; /* CTRL id */
+       ph->data[1] = oph->data[0]; /* PEP type */
+       ph->data[2] = code; /* error code, at an usual offset */
+       ph->data[3] = PAD;
+       ph->data[4] = PAD;
+
+       pn_skb_get_src_sockaddr(oskb, &dst);
+       return pn_skb_send(sk, skb, &dst);
+}
+
+static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct pnpipehdr *ph;
+       struct sk_buff *skb;
+
+       skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority);
+       if (!skb)
+               return -ENOMEM;
+       skb_set_owner_w(skb, sk);
+
+       skb_reserve(skb, MAX_PNPIPE_HEADER + 4);
+       __skb_push(skb, sizeof(*ph) + 4);
+       skb_reset_transport_header(skb);
+       ph = pnp_hdr(skb);
+       ph->utid = 0;
+       ph->message_id = PNS_PEP_STATUS_IND;
+       ph->pipe_handle = pn->pipe_handle;
+       ph->pep_type = PN_PEP_TYPE_COMMON;
+       ph->data[1] = type;
+       ph->data[2] = PAD;
+       ph->data[3] = PAD;
+       ph->data[4] = status;
+
+       return pn_skb_send(sk, skb, &pipe_srv);
+}
+
+/* Send our RX flow control information to the sender.
+ * Socket must be locked. */
+static void pipe_grant_credits(struct sock *sk)
+{
+       struct pep_sock *pn = pep_sk(sk);
+
+       BUG_ON(sk->sk_state != TCP_ESTABLISHED);
+
+       switch (pn->rx_fc) {
+       case PN_LEGACY_FLOW_CONTROL: /* TODO */
+               break;
+       case PN_ONE_CREDIT_FLOW_CONTROL:
+               pipe_snd_status(sk, PN_PEP_IND_FLOW_CONTROL,
+                               PEP_IND_READY, GFP_ATOMIC);
+               pn->rx_credits = 1;
+               break;
+       case PN_MULTI_CREDIT_FLOW_CONTROL:
+               if ((pn->rx_credits + CREDITS_THR) > CREDITS_MAX)
+                       break;
+               if (pipe_snd_status(sk, PN_PEP_IND_ID_MCFC_GRANT_CREDITS,
+                                       CREDITS_MAX - pn->rx_credits,
+                                       GFP_ATOMIC) == 0)
+                       pn->rx_credits = CREDITS_MAX;
+               break;
+       }
+}
+
+static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct pnpipehdr *hdr = pnp_hdr(skb);
+
+       if (!pskb_may_pull(skb, sizeof(*hdr) + 4))
+               return -EINVAL;
+
+       if (hdr->data[0] != PN_PEP_TYPE_COMMON) {
+               LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n",
+                               (unsigned)hdr->data[0]);
+               return -EOPNOTSUPP;
+       }
+
+       switch (hdr->data[1]) {
+       case PN_PEP_IND_FLOW_CONTROL:
+               switch (pn->tx_fc) {
+               case PN_LEGACY_FLOW_CONTROL:
+                       switch (hdr->data[4]) {
+                       case PEP_IND_BUSY:
+                               pn->tx_credits = 0;
+                               break;
+                       case PEP_IND_READY:
+                               pn->tx_credits = 1;
+                               break;
+                       }
+                       break;
+               case PN_ONE_CREDIT_FLOW_CONTROL:
+                       if (hdr->data[4] == PEP_IND_READY)
+                               pn->tx_credits = 1;
+                       break;
+               }
+               break;
+
+       case PN_PEP_IND_ID_MCFC_GRANT_CREDITS:
+               if (pn->tx_fc != PN_MULTI_CREDIT_FLOW_CONTROL)
+                       break;
+               if (pn->tx_credits + hdr->data[4] > 0xff)
+                       pn->tx_credits = 0xff;
+               else
+                       pn->tx_credits += hdr->data[4];
+               break;
+
+       default:
+               LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP indication: %u\n",
+                               (unsigned)hdr->data[1]);
+               return -EOPNOTSUPP;
+       }
+       if (pn->tx_credits)
+               sk->sk_write_space(sk);
+       return 0;
+}
+
+static int pipe_rcv_created(struct sock *sk, struct sk_buff *skb)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct pnpipehdr *hdr = pnp_hdr(skb);
+       u8 n_sb = hdr->data[0];
+
+       pn->rx_fc = pn->tx_fc = PN_LEGACY_FLOW_CONTROL;
+       __skb_pull(skb, sizeof(*hdr));
+       while (n_sb > 0) {
+               u8 type, buf[2], len = sizeof(buf);
+               u8 *data = pep_get_sb(skb, &type, &len, buf);
+
+               if (data == NULL)
+                       return -EINVAL;
+               switch (type) {
+               case PN_PIPE_SB_NEGOTIATED_FC:
+                       if (len < 2 || (data[0] | data[1]) > 3)
+                               break;
+                       pn->tx_fc = data[0] & 3;
+                       pn->rx_fc = data[1] & 3;
+                       break;
+               }
+               n_sb--;
+       }
+       return 0;
+}
+
+/* Queue an skb to a connected sock.
+ * Socket lock must be held. */
+static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct pnpipehdr *hdr = pnp_hdr(skb);
+       struct sk_buff_head *queue;
+       int err = 0;
+
+       BUG_ON(sk->sk_state == TCP_CLOSE_WAIT);
+
+       switch (hdr->message_id) {
+       case PNS_PEP_CONNECT_REQ:
+               pep_reject_conn(sk, skb, PN_PIPE_ERR_PEP_IN_USE);
+               break;
+
+       case PNS_PEP_DISCONNECT_REQ:
+               pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
+               sk->sk_state = TCP_CLOSE_WAIT;
+               if (!sock_flag(sk, SOCK_DEAD))
+                       sk->sk_state_change(sk);
+               break;
+
+       case PNS_PEP_ENABLE_REQ:
+               /* Wait for PNS_PIPE_(ENABLED|REDIRECTED)_IND */
+               pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
+               break;
+
+       case PNS_PEP_RESET_REQ:
+               switch (hdr->state_after_reset) {
+               case PN_PIPE_DISABLE:
+                       pn->init_enable = 0;
+                       break;
+               case PN_PIPE_ENABLE:
+                       pn->init_enable = 1;
+                       break;
+               default: /* not allowed to send an error here!? */
+                       err = -EINVAL;
+                       goto out;
+               }
+               /* fall through */
+       case PNS_PEP_DISABLE_REQ:
+               pn->tx_credits = 0;
+               pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
+               break;
+
+       case PNS_PEP_CTRL_REQ:
+               if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX)
+                       break;
+               __skb_pull(skb, 4);
+               queue = &pn->ctrlreq_queue;
+               goto queue;
+
+       case PNS_PIPE_DATA:
+               __skb_pull(skb, 3); /* Pipe data header */
+               if (!pn_flow_safe(pn->rx_fc)) {
+                       err = sock_queue_rcv_skb(sk, skb);
+                       if (!err)
+                               return 0;
+                       break;
+               }
+
+               if (pn->rx_credits == 0) {
+                       err = -ENOBUFS;
+                       break;
+               }
+               pn->rx_credits--;
+               queue = &sk->sk_receive_queue;
+               goto queue;
+
+       case PNS_PEP_STATUS_IND:
+               pipe_rcv_status(sk, skb);
+               break;
+
+       case PNS_PIPE_REDIRECTED_IND:
+               err = pipe_rcv_created(sk, skb);
+               break;
+
+       case PNS_PIPE_CREATED_IND:
+               err = pipe_rcv_created(sk, skb);
+               if (err)
+                       break;
+               /* fall through */
+       case PNS_PIPE_RESET_IND:
+               if (!pn->init_enable)
+                       break;
+               /* fall through */
+       case PNS_PIPE_ENABLED_IND:
+               if (!pn_flow_safe(pn->tx_fc)) {
+                       pn->tx_credits = 1;
+                       sk->sk_write_space(sk);
+               }
+               if (sk->sk_state == TCP_ESTABLISHED)
+                       break; /* Nothing to do */
+               sk->sk_state = TCP_ESTABLISHED;
+               pipe_grant_credits(sk);
+               break;
+
+       case PNS_PIPE_DISABLED_IND:
+               sk->sk_state = TCP_SYN_RECV;
+               pn->rx_credits = 0;
+               break;
+
+       default:
+               LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP message: %u\n",
+                               hdr->message_id);
+               err = -EINVAL;
+       }
+out:
+       kfree_skb(skb);
+       return err;
+
+queue:
+       skb->dev = NULL;
+       skb_set_owner_r(skb, sk);
+       err = skb->len;
+       skb_queue_tail(queue, skb);
+       if (!sock_flag(sk, SOCK_DEAD))
+               sk->sk_data_ready(sk, err);
+       return 0;
+}
+
+/* Destroy connected sock. */
+static void pipe_destruct(struct sock *sk)
+{
+       struct pep_sock *pn = pep_sk(sk);
+
+       skb_queue_purge(&sk->sk_receive_queue);
+       skb_queue_purge(&pn->ctrlreq_queue);
+}
+
+static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
+{
+       struct sock *newsk;
+       struct pep_sock *newpn, *pn = pep_sk(sk);
+       struct pnpipehdr *hdr;
+       struct sockaddr_pn dst;
+       u16 peer_type;
+       u8 pipe_handle, enabled, n_sb;
+
+       if (!pskb_pull(skb, sizeof(*hdr) + 4))
+               return -EINVAL;
+
+       hdr = pnp_hdr(skb);
+       pipe_handle = hdr->pipe_handle;
+       switch (hdr->state_after_connect) {
+       case PN_PIPE_DISABLE:
+               enabled = 0;
+               break;
+       case PN_PIPE_ENABLE:
+               enabled = 1;
+               break;
+       default:
+               pep_reject_conn(sk, skb, PN_PIPE_ERR_INVALID_PARAM);
+               return -EINVAL;
+       }
+       peer_type = hdr->other_pep_type << 8;
+
+       if (unlikely(sk->sk_state != TCP_LISTEN) || sk_acceptq_is_full(sk)) {
+               pep_reject_conn(sk, skb, PN_PIPE_ERR_PEP_IN_USE);
+               return -ENOBUFS;
+       }
+
+       /* Parse sub-blocks (options) */
+       n_sb = hdr->data[4];
+       while (n_sb > 0) {
+               u8 type, buf[1], len = sizeof(buf);
+               const u8 *data = pep_get_sb(skb, &type, &len, buf);
+
+               if (data == NULL)
+                       return -EINVAL;
+               switch (type) {
+               case PN_PIPE_SB_CONNECT_REQ_PEP_SUB_TYPE:
+                       if (len < 1)
+                               return -EINVAL;
+                       peer_type = (peer_type & 0xff00) | data[0];
+                       break;
+               }
+               n_sb--;
+       }
+
+       skb = skb_clone(skb, GFP_ATOMIC);
+       if (!skb)
+               return -ENOMEM;
+
+       /* Create a new to-be-accepted sock */
+       newsk = sk_alloc(sock_net(sk), PF_PHONET, GFP_ATOMIC, sk->sk_prot);
+       if (!newsk) {
+               kfree_skb(skb);
+               return -ENOMEM;
+       }
+       sock_init_data(NULL, newsk);
+       newsk->sk_state = TCP_SYN_RECV;
+       newsk->sk_backlog_rcv = pipe_do_rcv;
+       newsk->sk_protocol = sk->sk_protocol;
+       newsk->sk_destruct = pipe_destruct;
+
+       newpn = pep_sk(newsk);
+       pn_skb_get_dst_sockaddr(skb, &dst);
+       newpn->pn_sk.sobject = pn_sockaddr_get_object(&dst);
+       newpn->pn_sk.resource = pn->pn_sk.resource;
+       skb_queue_head_init(&newpn->ctrlreq_queue);
+       newpn->pipe_handle = pipe_handle;
+       newpn->peer_type = peer_type;
+       newpn->rx_credits = newpn->tx_credits = 0;
+       newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL;
+       newpn->init_enable = enabled;
+
+       BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue));
+       skb_queue_head(&newsk->sk_receive_queue, skb);
+       if (!sock_flag(sk, SOCK_DEAD))
+               sk->sk_data_ready(sk, 0);
+
+       sk_acceptq_added(sk);
+       sk_add_node(newsk, &pn->ackq);
+       return 0;
+}
+
+/* Listening sock must be locked */
+static struct sock *pep_find_pipe(const struct hlist_head *hlist,
+                                       const struct sockaddr_pn *dst,
+                                       u8 pipe_handle)
+{
+       struct hlist_node *node;
+       struct sock *sknode;
+       u16 dobj = pn_sockaddr_get_object(dst);
+
+       sk_for_each(sknode, node, hlist) {
+               struct pep_sock *pnnode = pep_sk(sknode);
+
+               /* Ports match, but addresses might not: */
+               if (pnnode->pn_sk.sobject != dobj)
+                       continue;
+               if (pnnode->pipe_handle != pipe_handle)
+                       continue;
+               if (sknode->sk_state == TCP_CLOSE_WAIT)
+                       continue;
+
+               sock_hold(sknode);
+               return sknode;
+       }
+       return NULL;
+}
+
+/*
+ * Deliver an skb to a listening sock.
+ * Socket lock must be held.
+ * We then queue the skb to the right connected sock (if any).
+ */
+static int pep_do_rcv(struct sock *sk, struct sk_buff *skb)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct sock *sknode;
+       struct pnpipehdr *hdr = pnp_hdr(skb);
+       struct sockaddr_pn dst;
+       int err = NET_RX_SUCCESS;
+       u8 pipe_handle;
+
+       if (!pskb_may_pull(skb, sizeof(*hdr)))
+               goto drop;
+
+       hdr = pnp_hdr(skb);
+       pipe_handle = hdr->pipe_handle;
+       if (pipe_handle == PN_PIPE_INVALID_HANDLE)
+               goto drop;
+
+       pn_skb_get_dst_sockaddr(skb, &dst);
+
+       /* Look for an existing pipe handle */
+       sknode = pep_find_pipe(&pn->hlist, &dst, pipe_handle);
+       if (sknode)
+               return sk_receive_skb(sknode, skb, 1);
+
+       /* Look for a pipe handle pending accept */
+       sknode = pep_find_pipe(&pn->ackq, &dst, pipe_handle);
+       if (sknode) {
+               sock_put(sknode);
+               if (net_ratelimit())
+                       printk(KERN_WARNING"Phonet unconnected PEP ignored");
+               err = NET_RX_DROP;
+               goto drop;
+       }
+
+       switch (hdr->message_id) {
+       case PNS_PEP_CONNECT_REQ:
+               err = pep_connreq_rcv(sk, skb);
+               break;
+
+       case PNS_PEP_DISCONNECT_REQ:
+               pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
+               break;
+
+       case PNS_PEP_CTRL_REQ:
+               pep_ctrlreq_error(sk, skb, PN_PIPE_INVALID_HANDLE, GFP_ATOMIC);
+               break;
+
+       case PNS_PEP_RESET_REQ:
+       case PNS_PEP_ENABLE_REQ:
+       case PNS_PEP_DISABLE_REQ:
+               /* invalid handle is not even allowed here! */
+       default:
+               err = NET_RX_DROP;
+       }
+drop:
+       kfree_skb(skb);
+       return err;
+}
+
+/* associated socket ceases to exist */
+static void pep_sock_close(struct sock *sk, long timeout)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       int ifindex = 0;
+
+       sk_common_release(sk);
+
+       lock_sock(sk);
+       if (sk->sk_state == TCP_LISTEN) {
+               /* Destroy the listen queue */
+               struct sock *sknode;
+               struct hlist_node *p, *n;
+
+               sk_for_each_safe(sknode, p, n, &pn->ackq)
+                       sk_del_node_init(sknode);
+               sk->sk_state = TCP_CLOSE;
+       }
+       ifindex = pn->ifindex;
+       pn->ifindex = 0;
+       release_sock(sk);
+
+       if (ifindex)
+               gprs_detach(sk);
+}
+
+static int pep_wait_connreq(struct sock *sk, int noblock)
+{
+       struct task_struct *tsk = current;
+       struct pep_sock *pn = pep_sk(sk);
+       long timeo = sock_rcvtimeo(sk, noblock);
+
+       for (;;) {
+               DEFINE_WAIT(wait);
+
+               if (sk->sk_state != TCP_LISTEN)
+                       return -EINVAL;
+               if (!hlist_empty(&pn->ackq))
+                       break;
+               if (!timeo)
+                       return -EWOULDBLOCK;
+               if (signal_pending(tsk))
+                       return sock_intr_errno(timeo);
+
+               prepare_to_wait_exclusive(&sk->sk_socket->wait, &wait,
+                                               TASK_INTERRUPTIBLE);
+               release_sock(sk);
+               timeo = schedule_timeout(timeo);
+               lock_sock(sk);
+               finish_wait(&sk->sk_socket->wait, &wait);
+       }
+
+       return 0;
+}
+
+static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct sock *newsk = NULL;
+       struct sk_buff *oskb;
+       int err;
+
+       lock_sock(sk);
+       err = pep_wait_connreq(sk, flags & O_NONBLOCK);
+       if (err)
+               goto out;
+
+       newsk = __sk_head(&pn->ackq);
+
+       oskb = skb_dequeue(&newsk->sk_receive_queue);
+       err = pep_accept_conn(newsk, oskb);
+       if (err) {
+               skb_queue_head(&newsk->sk_receive_queue, oskb);
+               newsk = NULL;
+               goto out;
+       }
+
+       sock_hold(sk);
+       pep_sk(newsk)->listener = sk;
+
+       sock_hold(newsk);
+       sk_del_node_init(newsk);
+       sk_acceptq_removed(sk);
+       sk_add_node(newsk, &pn->hlist);
+       __sock_put(newsk);
+
+out:
+       release_sock(sk);
+       *errp = err;
+       return newsk;
+}
+
+static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       int answ;
+
+       switch (cmd) {
+       case SIOCINQ:
+               if (sk->sk_state == TCP_LISTEN)
+                       return -EINVAL;
+
+               lock_sock(sk);
+               if (sock_flag(sk, SOCK_URGINLINE)
+                && !skb_queue_empty(&pn->ctrlreq_queue))
+                       answ = skb_peek(&pn->ctrlreq_queue)->len;
+               else if (!skb_queue_empty(&sk->sk_receive_queue))
+                       answ = skb_peek(&sk->sk_receive_queue)->len;
+               else
+                       answ = 0;
+               release_sock(sk);
+               return put_user(answ, (int __user *)arg);
+       }
+
+       return -ENOIOCTLCMD;
+}
+
+static int pep_init(struct sock *sk)
+{
+       struct pep_sock *pn = pep_sk(sk);
+
+       INIT_HLIST_HEAD(&pn->ackq);
+       INIT_HLIST_HEAD(&pn->hlist);
+       skb_queue_head_init(&pn->ctrlreq_queue);
+       pn->pipe_handle = PN_PIPE_INVALID_HANDLE;
+       return 0;
+}
+
+static int pep_setsockopt(struct sock *sk, int level, int optname,
+                               char __user *optval, int optlen)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       int val = 0, err = 0;
+
+       if (level != SOL_PNPIPE)
+               return -ENOPROTOOPT;
+       if (optlen >= sizeof(int)) {
+               if (get_user(val, (int __user *) optval))
+                       return -EFAULT;
+       }
+
+       lock_sock(sk);
+       switch (optname) {
+       case PNPIPE_ENCAP:
+               if (val && val != PNPIPE_ENCAP_IP) {
+                       err = -EINVAL;
+                       break;
+               }
+               if (!pn->ifindex == !val)
+                       break; /* Nothing to do! */
+               if (!capable(CAP_NET_ADMIN)) {
+                       err = -EPERM;
+                       break;
+               }
+               if (val) {
+                       release_sock(sk);
+                       err = gprs_attach(sk);
+                       if (err > 0) {
+                               pn->ifindex = err;
+                               err = 0;
+                       }
+               } else {
+                       pn->ifindex = 0;
+                       release_sock(sk);
+                       gprs_detach(sk);
+                       err = 0;
+               }
+               goto out_norel;
+       default:
+               err = -ENOPROTOOPT;
+       }
+       release_sock(sk);
+
+out_norel:
+       return err;
+}
+
+static int pep_getsockopt(struct sock *sk, int level, int optname,
+                               char __user *optval, int __user *optlen)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       int len, val;
+
+       if (level != SOL_PNPIPE)
+               return -ENOPROTOOPT;
+       if (get_user(len, optlen))
+               return -EFAULT;
+
+       switch (optname) {
+       case PNPIPE_ENCAP:
+               val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE;
+               break;
+       case PNPIPE_IFINDEX:
+               val = pn->ifindex;
+               break;
+       default:
+               return -ENOPROTOOPT;
+       }
+
+       len = min_t(unsigned int, sizeof(int), len);
+       if (put_user(len, optlen))
+               return -EFAULT;
+       if (put_user(val, (int __user *) optval))
+               return -EFAULT;
+       return 0;
+}
+
+static int pipe_skb_send(struct sock *sk, struct sk_buff *skb)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct pnpipehdr *ph;
+
+       skb_push(skb, 3);
+       skb_reset_transport_header(skb);
+       ph = pnp_hdr(skb);
+       ph->utid = 0;
+       ph->message_id = PNS_PIPE_DATA;
+       ph->pipe_handle = pn->pipe_handle;
+       if (pn_flow_safe(pn->tx_fc) && pn->tx_credits)
+               pn->tx_credits--;
+
+       return pn_skb_send(sk, skb, &pipe_srv);
+}
+
+static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
+                       struct msghdr *msg, size_t len)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct sk_buff *skb = NULL;
+       long timeo;
+       int flags = msg->msg_flags;
+       int err, done;
+
+       if (msg->msg_flags & MSG_OOB || !(msg->msg_flags & MSG_EOR))
+               return -EOPNOTSUPP;
+
+       lock_sock(sk);
+       timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
+       if ((1 << sk->sk_state) & (TCPF_LISTEN|TCPF_CLOSE)) {
+               err = -ENOTCONN;
+               goto out;
+       }
+       if (sk->sk_state != TCP_ESTABLISHED) {
+               /* Wait until the pipe gets to enabled state */
+disabled:
+               err = sk_stream_wait_connect(sk, &timeo);
+               if (err)
+                       goto out;
+
+               if (sk->sk_state == TCP_CLOSE_WAIT) {
+                       err = -ECONNRESET;
+                       goto out;
+               }
+       }
+       BUG_ON(sk->sk_state != TCP_ESTABLISHED);
+
+       /* Wait until flow control allows TX */
+       done = pn->tx_credits > 0;
+       while (!done) {
+               DEFINE_WAIT(wait);
+
+               if (!timeo) {
+                       err = -EAGAIN;
+                       goto out;
+               }
+               if (signal_pending(current)) {
+                       err = sock_intr_errno(timeo);
+                       goto out;
+               }
+
+               prepare_to_wait(&sk->sk_socket->wait, &wait,
+                               TASK_INTERRUPTIBLE);
+               done = sk_wait_event(sk, &timeo, pn->tx_credits > 0);
+               finish_wait(&sk->sk_socket->wait, &wait);
+
+               if (sk->sk_state != TCP_ESTABLISHED)
+                       goto disabled;
+       }
+
+       if (!skb) {
+               skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len,
+                                               flags & MSG_DONTWAIT, &err);
+               if (skb == NULL)
+                       goto out;
+               skb_reserve(skb, MAX_PHONET_HEADER + 3);
+
+               if (sk->sk_state != TCP_ESTABLISHED || !pn->tx_credits)
+                       goto disabled; /* sock_alloc_send_skb might sleep */
+       }
+
+       err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+       if (err < 0)
+               goto out;
+
+       err = pipe_skb_send(sk, skb);
+       if (err >= 0)
+               err = len; /* success! */
+       skb = NULL;
+out:
+       release_sock(sk);
+       kfree_skb(skb);
+       return err;
+}
+
+int pep_writeable(struct sock *sk)
+{
+       struct pep_sock *pn = pep_sk(sk);
+
+       return (sk->sk_state == TCP_ESTABLISHED) ? pn->tx_credits : 0;
+}
+
+int pep_write(struct sock *sk, struct sk_buff *skb)
+{
+       struct sk_buff *rskb, *fs;
+       int flen = 0;
+
+       rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC);
+       if (!rskb) {
+               kfree_skb(skb);
+               return -ENOMEM;
+       }
+       skb_shinfo(rskb)->frag_list = skb;
+       rskb->len += skb->len;
+       rskb->data_len += rskb->len;
+       rskb->truesize += rskb->len;
+
+       /* Avoid nested fragments */
+       for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
+               flen += fs->len;
+       skb->next = skb_shinfo(skb)->frag_list;
+       skb_shinfo(skb)->frag_list = NULL;
+       skb->len -= flen;
+       skb->data_len -= flen;
+       skb->truesize -= flen;
+
+       skb_reserve(rskb, MAX_PHONET_HEADER + 3);
+       return pipe_skb_send(sk, rskb);
+}
+
+struct sk_buff *pep_read(struct sock *sk)
+{
+       struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
+
+       if (sk->sk_state == TCP_ESTABLISHED)
+               pipe_grant_credits(sk);
+       return skb;
+}
+
+static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,
+                       struct msghdr *msg, size_t len, int noblock,
+                       int flags, int *addr_len)
+{
+       struct sk_buff *skb;
+       int err;
+
+       if (unlikely(1 << sk->sk_state & (TCPF_LISTEN | TCPF_CLOSE)))
+               return -ENOTCONN;
+
+       if ((flags & MSG_OOB) || sock_flag(sk, SOCK_URGINLINE)) {
+               /* Dequeue and acknowledge control request */
+               struct pep_sock *pn = pep_sk(sk);
+
+               skb = skb_dequeue(&pn->ctrlreq_queue);
+               if (skb) {
+                       pep_ctrlreq_error(sk, skb, PN_PIPE_NO_ERROR,
+                                               GFP_KERNEL);
+                       msg->msg_flags |= MSG_OOB;
+                       goto copy;
+               }
+               if (flags & MSG_OOB)
+                       return -EINVAL;
+       }
+
+       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       lock_sock(sk);
+       if (skb == NULL) {
+               if (err == -ENOTCONN && sk->sk_state == TCP_CLOSE_WAIT)
+                       err = -ECONNRESET;
+               release_sock(sk);
+               return err;
+       }
+
+       if (sk->sk_state == TCP_ESTABLISHED)
+               pipe_grant_credits(sk);
+       release_sock(sk);
+copy:
+       msg->msg_flags |= MSG_EOR;
+       if (skb->len > len)
+               msg->msg_flags |= MSG_TRUNC;
+       else
+               len = skb->len;
+
+       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
+       if (!err)
+               err = (flags & MSG_TRUNC) ? skb->len : len;
+
+       skb_free_datagram(sk, skb);
+       return err;
+}
+
+static void pep_sock_unhash(struct sock *sk)
+{
+       struct pep_sock *pn = pep_sk(sk);
+       struct sock *skparent = NULL;
+
+       lock_sock(sk);
+       if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) {
+               skparent = pn->listener;
+               sk_del_node_init(sk);
+               release_sock(sk);
+
+               sk = skparent;
+               pn = pep_sk(skparent);
+               lock_sock(sk);
+       }
+       /* Unhash a listening sock only when it is closed
+        * and all of its active connected pipes are closed. */
+       if (hlist_empty(&pn->hlist))
+               pn_sock_unhash(&pn->pn_sk.sk);
+       release_sock(sk);
+
+       if (skparent)
+               sock_put(skparent);
+}
+
+static struct proto pep_proto = {
+       .close          = pep_sock_close,
+       .accept         = pep_sock_accept,
+       .ioctl          = pep_ioctl,
+       .init           = pep_init,
+       .setsockopt     = pep_setsockopt,
+       .getsockopt     = pep_getsockopt,
+       .sendmsg        = pep_sendmsg,
+       .recvmsg        = pep_recvmsg,
+       .backlog_rcv    = pep_do_rcv,
+       .hash           = pn_sock_hash,
+       .unhash         = pep_sock_unhash,
+       .get_port       = pn_sock_get_port,
+       .obj_size       = sizeof(struct pep_sock),
+       .owner          = THIS_MODULE,
+       .name           = "PNPIPE",
+};
+
+static struct phonet_protocol pep_pn_proto = {
+       .ops            = &phonet_stream_ops,
+       .prot           = &pep_proto,
+       .sock_type      = SOCK_SEQPACKET,
+};
+
+static int __init pep_register(void)
+{
+       return phonet_proto_register(PN_PROTO_PIPE, &pep_pn_proto);
+}
+
+static void __exit pep_unregister(void)
+{
+       phonet_proto_unregister(PN_PROTO_PIPE, &pep_pn_proto);
+}
+
+module_init(pep_register);
+module_exit(pep_unregister);
+MODULE_AUTHOR("Remi Denis-Courmont, Nokia");
+MODULE_DESCRIPTION("Phonet pipe protocol");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_NET_PF_PROTO(PF_PHONET, PN_PROTO_PIPE);
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
new file mode 100644 (file)
index 0000000..53be9fc
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * File: pn_dev.c
+ *
+ * Phonet network device
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+ * Original author: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/net.h>
+#include <linux/netdevice.h>
+#include <linux/phonet.h>
+#include <net/sock.h>
+#include <net/phonet/pn_dev.h>
+
+/* when accessing, remember to lock with spin_lock(&pndevs.lock); */
+struct phonet_device_list pndevs = {
+       .list = LIST_HEAD_INIT(pndevs.list),
+       .lock = __SPIN_LOCK_UNLOCKED(pndevs.lock),
+};
+
+/* Allocate new Phonet device. */
+static struct phonet_device *__phonet_device_alloc(struct net_device *dev)
+{
+       struct phonet_device *pnd = kmalloc(sizeof(*pnd), GFP_ATOMIC);
+       if (pnd == NULL)
+               return NULL;
+       pnd->netdev = dev;
+       bitmap_zero(pnd->addrs, 64);
+
+       list_add(&pnd->list, &pndevs.list);
+       return pnd;
+}
+
+static struct phonet_device *__phonet_get(struct net_device *dev)
+{
+       struct phonet_device *pnd;
+
+       list_for_each_entry(pnd, &pndevs.list, list) {
+               if (pnd->netdev == dev)
+                       return pnd;
+       }
+       return NULL;
+}
+
+static void __phonet_device_free(struct phonet_device *pnd)
+{
+       list_del(&pnd->list);
+       kfree(pnd);
+}
+
+struct net_device *phonet_device_get(struct net *net)
+{
+       struct phonet_device *pnd;
+       struct net_device *dev;
+
+       spin_lock_bh(&pndevs.lock);
+       list_for_each_entry(pnd, &pndevs.list, list) {
+               dev = pnd->netdev;
+               BUG_ON(!dev);
+
+               if (dev_net(dev) == net &&
+                       (dev->reg_state == NETREG_REGISTERED) &&
+                       ((pnd->netdev->flags & IFF_UP)) == IFF_UP)
+                       break;
+               dev = NULL;
+       }
+       if (dev)
+               dev_hold(dev);
+       spin_unlock_bh(&pndevs.lock);
+       return dev;
+}
+
+int phonet_address_add(struct net_device *dev, u8 addr)
+{
+       struct phonet_device *pnd;
+       int err = 0;
+
+       spin_lock_bh(&pndevs.lock);
+       /* Find or create Phonet-specific device data */
+       pnd = __phonet_get(dev);
+       if (pnd == NULL)
+               pnd = __phonet_device_alloc(dev);
+       if (unlikely(pnd == NULL))
+               err = -ENOMEM;
+       else if (test_and_set_bit(addr >> 2, pnd->addrs))
+               err = -EEXIST;
+       spin_unlock_bh(&pndevs.lock);
+       return err;
+}
+
+int phonet_address_del(struct net_device *dev, u8 addr)
+{
+       struct phonet_device *pnd;
+       int err = 0;
+
+       spin_lock_bh(&pndevs.lock);
+       pnd = __phonet_get(dev);
+       if (!pnd || !test_and_clear_bit(addr >> 2, pnd->addrs))
+               err = -EADDRNOTAVAIL;
+       if (bitmap_empty(pnd->addrs, 64))
+               __phonet_device_free(pnd);
+       spin_unlock_bh(&pndevs.lock);
+       return err;
+}
+
+/* Gets a source address toward a destination, through a interface. */
+u8 phonet_address_get(struct net_device *dev, u8 addr)
+{
+       struct phonet_device *pnd;
+
+       spin_lock_bh(&pndevs.lock);
+       pnd = __phonet_get(dev);
+       if (pnd) {
+               BUG_ON(bitmap_empty(pnd->addrs, 64));
+
+               /* Use same source address as destination, if possible */
+               if (!test_bit(addr >> 2, pnd->addrs))
+                       addr = find_first_bit(pnd->addrs, 64) << 2;
+       } else
+               addr = PN_NO_ADDR;
+       spin_unlock_bh(&pndevs.lock);
+       return addr;
+}
+
+int phonet_address_lookup(u8 addr)
+{
+       struct phonet_device *pnd;
+
+       spin_lock_bh(&pndevs.lock);
+       list_for_each_entry(pnd, &pndevs.list, list) {
+               /* Don't allow unregistering devices! */
+               if ((pnd->netdev->reg_state != NETREG_REGISTERED) ||
+                               ((pnd->netdev->flags & IFF_UP)) != IFF_UP)
+                       continue;
+
+               if (test_bit(addr >> 2, pnd->addrs)) {
+                       spin_unlock_bh(&pndevs.lock);
+                       return 0;
+               }
+       }
+       spin_unlock_bh(&pndevs.lock);
+       return -EADDRNOTAVAIL;
+}
+
+/* notify Phonet of device events */
+static int phonet_device_notify(struct notifier_block *me, unsigned long what,
+                               void *arg)
+{
+       struct net_device *dev = arg;
+
+       if (what == NETDEV_UNREGISTER) {
+               struct phonet_device *pnd;
+
+               /* Destroy phonet-specific device data */
+               spin_lock_bh(&pndevs.lock);
+               pnd = __phonet_get(dev);
+               if (pnd)
+                       __phonet_device_free(pnd);
+               spin_unlock_bh(&pndevs.lock);
+       }
+       return 0;
+
+}
+
+static struct notifier_block phonet_device_notifier = {
+       .notifier_call = phonet_device_notify,
+       .priority = 0,
+};
+
+/* Initialize Phonet devices list */
+void phonet_device_init(void)
+{
+       register_netdevice_notifier(&phonet_device_notifier);
+}
+
+void phonet_device_exit(void)
+{
+       struct phonet_device *pnd, *n;
+
+       rtnl_unregister_all(PF_PHONET);
+       rtnl_lock();
+       spin_lock_bh(&pndevs.lock);
+
+       list_for_each_entry_safe(pnd, n, &pndevs.list, list)
+               __phonet_device_free(pnd);
+
+       spin_unlock_bh(&pndevs.lock);
+       rtnl_unlock();
+       unregister_netdevice_notifier(&phonet_device_notifier);
+}
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
new file mode 100644 (file)
index 0000000..b1770d6
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * File: pn_netlink.c
+ *
+ * Phonet netlink interface
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+ * Original author: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/netlink.h>
+#include <linux/phonet.h>
+#include <net/sock.h>
+#include <net/phonet/pn_dev.h>
+
+static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
+                    u32 pid, u32 seq, int event);
+
+static void rtmsg_notify(int event, struct net_device *dev, u8 addr)
+{
+       struct sk_buff *skb;
+       int err = -ENOBUFS;
+
+       skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
+                       nla_total_size(1), GFP_KERNEL);
+       if (skb == NULL)
+               goto errout;
+       err = fill_addr(skb, dev, addr, 0, 0, event);
+       if (err < 0) {
+               WARN_ON(err == -EMSGSIZE);
+               kfree_skb(skb);
+               goto errout;
+       }
+       err = rtnl_notify(skb, dev_net(dev), 0,
+                         RTNLGRP_PHONET_IFADDR, NULL, GFP_KERNEL);
+errout:
+       if (err < 0)
+               rtnl_set_sk_err(dev_net(dev), RTNLGRP_PHONET_IFADDR, err);
+}
+
+static const struct nla_policy ifa_phonet_policy[IFA_MAX+1] = {
+       [IFA_LOCAL] = { .type = NLA_U8 },
+};
+
+static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
+{
+       struct net *net = sock_net(skb->sk);
+       struct nlattr *tb[IFA_MAX+1];
+       struct net_device *dev;
+       struct ifaddrmsg *ifm;
+       int err;
+       u8 pnaddr;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       ASSERT_RTNL();
+
+       err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_phonet_policy);
+       if (err < 0)
+               return err;
+
+       ifm = nlmsg_data(nlh);
+       if (tb[IFA_LOCAL] == NULL)
+               return -EINVAL;
+       pnaddr = nla_get_u8(tb[IFA_LOCAL]);
+       if (pnaddr & 3)
+               /* Phonet addresses only have 6 high-order bits */
+               return -EINVAL;
+
+       dev = __dev_get_by_index(net, ifm->ifa_index);
+       if (dev == NULL)
+               return -ENODEV;
+
+       if (nlh->nlmsg_type == RTM_NEWADDR)
+               err = phonet_address_add(dev, pnaddr);
+       else
+               err = phonet_address_del(dev, pnaddr);
+       if (!err)
+               rtmsg_notify(nlh->nlmsg_type, dev, pnaddr);
+       return err;
+}
+
+static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
+                       u32 pid, u32 seq, int event)
+{
+       struct ifaddrmsg *ifm;
+       struct nlmsghdr *nlh;
+
+       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), 0);
+       if (nlh == NULL)
+               return -EMSGSIZE;
+
+       ifm = nlmsg_data(nlh);
+       ifm->ifa_family = AF_PHONET;
+       ifm->ifa_prefixlen = 0;
+       ifm->ifa_flags = IFA_F_PERMANENT;
+       ifm->ifa_scope = RT_SCOPE_LINK;
+       ifm->ifa_index = dev->ifindex;
+       NLA_PUT_U8(skb, IFA_LOCAL, addr);
+       return nlmsg_end(skb, nlh);
+
+nla_put_failure:
+       nlmsg_cancel(skb, nlh);
+       return -EMSGSIZE;
+}
+
+static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+       struct phonet_device *pnd;
+       int dev_idx = 0, dev_start_idx = cb->args[0];
+       int addr_idx = 0, addr_start_idx = cb->args[1];
+
+       spin_lock_bh(&pndevs.lock);
+       list_for_each_entry(pnd, &pndevs.list, list) {
+               u8 addr;
+
+               if (dev_idx > dev_start_idx)
+                       addr_start_idx = 0;
+               if (dev_idx++ < dev_start_idx)
+                       continue;
+
+               addr_idx = 0;
+               for (addr = find_first_bit(pnd->addrs, 64); addr < 64;
+                       addr = find_next_bit(pnd->addrs, 64, 1+addr)) {
+                       if (addr_idx++ < addr_start_idx)
+                               continue;
+
+                       if (fill_addr(skb, pnd->netdev, addr << 2,
+                                        NETLINK_CB(cb->skb).pid,
+                                       cb->nlh->nlmsg_seq, RTM_NEWADDR))
+                               goto out;
+               }
+       }
+
+out:
+       spin_unlock_bh(&pndevs.lock);
+       cb->args[0] = dev_idx;
+       cb->args[1] = addr_idx;
+
+       return skb->len;
+}
+
+void __init phonet_netlink_register(void)
+{
+       rtnl_register(PF_PHONET, RTM_NEWADDR, addr_doit, NULL);
+       rtnl_register(PF_PHONET, RTM_DELADDR, addr_doit, NULL);
+       rtnl_register(PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit);
+}
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
new file mode 100644 (file)
index 0000000..d817401
--- /dev/null
@@ -0,0 +1,411 @@
+/*
+ * File: socket.c
+ *
+ * Phonet sockets
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+ * Original author: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/net.h>
+#include <linux/poll.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+
+#include <linux/phonet.h>
+#include <net/phonet/phonet.h>
+#include <net/phonet/pep.h>
+#include <net/phonet/pn_dev.h>
+
+static int pn_socket_release(struct socket *sock)
+{
+       struct sock *sk = sock->sk;
+
+       if (sk) {
+               sock->sk = NULL;
+               sk->sk_prot->close(sk, 0);
+       }
+       return 0;
+}
+
+static struct  {
+       struct hlist_head hlist;
+       spinlock_t lock;
+} pnsocks = {
+       .hlist = HLIST_HEAD_INIT,
+       .lock = __SPIN_LOCK_UNLOCKED(pnsocks.lock),
+};
+
+/*
+ * Find address based on socket address, match only certain fields.
+ * Also grab sock if it was found. Remember to sock_put it later.
+ */
+struct sock *pn_find_sock_by_sa(const struct sockaddr_pn *spn)
+{
+       struct hlist_node *node;
+       struct sock *sknode;
+       struct sock *rval = NULL;
+       u16 obj = pn_sockaddr_get_object(spn);
+       u8 res = spn->spn_resource;
+
+       spin_lock_bh(&pnsocks.lock);
+
+       sk_for_each(sknode, node, &pnsocks.hlist) {
+               struct pn_sock *pn = pn_sk(sknode);
+               BUG_ON(!pn->sobject); /* unbound socket */
+
+               if (pn_port(obj)) {
+                       /* Look up socket by port */
+                       if (pn_port(pn->sobject) != pn_port(obj))
+                               continue;
+               } else {
+                       /* If port is zero, look up by resource */
+                       if (pn->resource != res)
+                               continue;
+               }
+               if (pn_addr(pn->sobject)
+                && pn_addr(pn->sobject) != pn_addr(obj))
+                       continue;
+
+               rval = sknode;
+               sock_hold(sknode);
+               break;
+       }
+
+       spin_unlock_bh(&pnsocks.lock);
+
+       return rval;
+
+}
+
+void pn_sock_hash(struct sock *sk)
+{
+       spin_lock_bh(&pnsocks.lock);
+       sk_add_node(sk, &pnsocks.hlist);
+       spin_unlock_bh(&pnsocks.lock);
+}
+EXPORT_SYMBOL(pn_sock_hash);
+
+void pn_sock_unhash(struct sock *sk)
+{
+       spin_lock_bh(&pnsocks.lock);
+       sk_del_node_init(sk);
+       spin_unlock_bh(&pnsocks.lock);
+}
+EXPORT_SYMBOL(pn_sock_unhash);
+
+static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
+{
+       struct sock *sk = sock->sk;
+       struct pn_sock *pn = pn_sk(sk);
+       struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
+       int err;
+       u16 handle;
+       u8 saddr;
+
+       if (sk->sk_prot->bind)
+               return sk->sk_prot->bind(sk, addr, len);
+
+       if (len < sizeof(struct sockaddr_pn))
+               return -EINVAL;
+       if (spn->spn_family != AF_PHONET)
+               return -EAFNOSUPPORT;
+
+       handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr);
+       saddr = pn_addr(handle);
+       if (saddr && phonet_address_lookup(saddr))
+               return -EADDRNOTAVAIL;
+
+       lock_sock(sk);
+       if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) {
+               err = -EINVAL; /* attempt to rebind */
+               goto out;
+       }
+       err = sk->sk_prot->get_port(sk, pn_port(handle));
+       if (err)
+               goto out;
+
+       /* get_port() sets the port, bind() sets the address if applicable */
+       pn->sobject = pn_object(saddr, pn_port(pn->sobject));
+       pn->resource = spn->spn_resource;
+
+       /* Enable RX on the socket */
+       sk->sk_prot->hash(sk);
+out:
+       release_sock(sk);
+       return err;
+}
+
+static int pn_socket_autobind(struct socket *sock)
+{
+       struct sockaddr_pn sa;
+       int err;
+
+       memset(&sa, 0, sizeof(sa));
+       sa.spn_family = AF_PHONET;
+       err = pn_socket_bind(sock, (struct sockaddr *)&sa,
+                               sizeof(struct sockaddr_pn));
+       if (err != -EINVAL)
+               return err;
+       BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
+       return 0; /* socket was already bound */
+}
+
+static int pn_socket_accept(struct socket *sock, struct socket *newsock,
+                               int flags)
+{
+       struct sock *sk = sock->sk;
+       struct sock *newsk;
+       int err;
+
+       newsk = sk->sk_prot->accept(sk, flags, &err);
+       if (!newsk)
+               return err;
+
+       lock_sock(newsk);
+       sock_graft(newsk, newsock);
+       newsock->state = SS_CONNECTED;
+       release_sock(newsk);
+       return 0;
+}
+
+static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
+                               int *sockaddr_len, int peer)
+{
+       struct sock *sk = sock->sk;
+       struct pn_sock *pn = pn_sk(sk);
+
+       memset(addr, 0, sizeof(struct sockaddr_pn));
+       addr->sa_family = AF_PHONET;
+       if (!peer) /* Race with bind() here is userland's problem. */
+               pn_sockaddr_set_object((struct sockaddr_pn *)addr,
+                                       pn->sobject);
+
+       *sockaddr_len = sizeof(struct sockaddr_pn);
+       return 0;
+}
+
+static unsigned int pn_socket_poll(struct file *file, struct socket *sock,
+                                       poll_table *wait)
+{
+       struct sock *sk = sock->sk;
+       struct pep_sock *pn = pep_sk(sk);
+       unsigned int mask = 0;
+
+       poll_wait(file, &sock->wait, wait);
+
+       switch (sk->sk_state) {
+       case TCP_LISTEN:
+               return hlist_empty(&pn->ackq) ? 0 : POLLIN;
+       case TCP_CLOSE:
+               return POLLERR;
+       }
+
+       if (!skb_queue_empty(&sk->sk_receive_queue))
+               mask |= POLLIN | POLLRDNORM;
+       if (!skb_queue_empty(&pn->ctrlreq_queue))
+               mask |= POLLPRI;
+       if (!mask && sk->sk_state == TCP_CLOSE_WAIT)
+               return POLLHUP;
+
+       if (sk->sk_state == TCP_ESTABLISHED && pn->tx_credits)
+               mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
+
+       return mask;
+}
+
+static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
+                               unsigned long arg)
+{
+       struct sock *sk = sock->sk;
+       struct pn_sock *pn = pn_sk(sk);
+
+       if (cmd == SIOCPNGETOBJECT) {
+               struct net_device *dev;
+               u16 handle;
+               u8 saddr;
+
+               if (get_user(handle, (__u16 __user *)arg))
+                       return -EFAULT;
+
+               lock_sock(sk);
+               if (sk->sk_bound_dev_if)
+                       dev = dev_get_by_index(sock_net(sk),
+                                               sk->sk_bound_dev_if);
+               else
+                       dev = phonet_device_get(sock_net(sk));
+               if (dev && (dev->flags & IFF_UP))
+                       saddr = phonet_address_get(dev, pn_addr(handle));
+               else
+                       saddr = PN_NO_ADDR;
+               release_sock(sk);
+
+               if (dev)
+                       dev_put(dev);
+               if (saddr == PN_NO_ADDR)
+                       return -EHOSTUNREACH;
+
+               handle = pn_object(saddr, pn_port(pn->sobject));
+               return put_user(handle, (__u16 __user *)arg);
+       }
+
+       return sk->sk_prot->ioctl(sk, cmd, arg);
+}
+
+static int pn_socket_listen(struct socket *sock, int backlog)
+{
+       struct sock *sk = sock->sk;
+       int err = 0;
+
+       if (sock->state != SS_UNCONNECTED)
+               return -EINVAL;
+       if (pn_socket_autobind(sock))
+               return -ENOBUFS;
+
+       lock_sock(sk);
+       if (sk->sk_state != TCP_CLOSE) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       sk->sk_state = TCP_LISTEN;
+       sk->sk_ack_backlog = 0;
+       sk->sk_max_ack_backlog = backlog;
+out:
+       release_sock(sk);
+       return err;
+}
+
+static int pn_socket_sendmsg(struct kiocb *iocb, struct socket *sock,
+                               struct msghdr *m, size_t total_len)
+{
+       struct sock *sk = sock->sk;
+
+       if (pn_socket_autobind(sock))
+               return -EAGAIN;
+
+       return sk->sk_prot->sendmsg(iocb, sk, m, total_len);
+}
+
+const struct proto_ops phonet_dgram_ops = {
+       .family         = AF_PHONET,
+       .owner          = THIS_MODULE,
+       .release        = pn_socket_release,
+       .bind           = pn_socket_bind,
+       .connect        = sock_no_connect,
+       .socketpair     = sock_no_socketpair,
+       .accept         = sock_no_accept,
+       .getname        = pn_socket_getname,
+       .poll           = datagram_poll,
+       .ioctl          = pn_socket_ioctl,
+       .listen         = sock_no_listen,
+       .shutdown       = sock_no_shutdown,
+       .setsockopt     = sock_no_setsockopt,
+       .getsockopt     = sock_no_getsockopt,
+#ifdef CONFIG_COMPAT
+       .compat_setsockopt = sock_no_setsockopt,
+       .compat_getsockopt = sock_no_getsockopt,
+#endif
+       .sendmsg        = pn_socket_sendmsg,
+       .recvmsg        = sock_common_recvmsg,
+       .mmap           = sock_no_mmap,
+       .sendpage       = sock_no_sendpage,
+};
+
+const struct proto_ops phonet_stream_ops = {
+       .family         = AF_PHONET,
+       .owner          = THIS_MODULE,
+       .release        = pn_socket_release,
+       .bind           = pn_socket_bind,
+       .connect        = sock_no_connect,
+       .socketpair     = sock_no_socketpair,
+       .accept         = pn_socket_accept,
+       .getname        = pn_socket_getname,
+       .poll           = pn_socket_poll,
+       .ioctl          = pn_socket_ioctl,
+       .listen         = pn_socket_listen,
+       .shutdown       = sock_no_shutdown,
+       .setsockopt     = sock_common_setsockopt,
+       .getsockopt     = sock_common_getsockopt,
+#ifdef CONFIG_COMPAT
+       .compat_setsockopt = compat_sock_common_setsockopt,
+       .compat_getsockopt = compat_sock_common_getsockopt,
+#endif
+       .sendmsg        = pn_socket_sendmsg,
+       .recvmsg        = sock_common_recvmsg,
+       .mmap           = sock_no_mmap,
+       .sendpage       = sock_no_sendpage,
+};
+EXPORT_SYMBOL(phonet_stream_ops);
+
+static DEFINE_MUTEX(port_mutex);
+
+/* allocate port for a socket */
+int pn_sock_get_port(struct sock *sk, unsigned short sport)
+{
+       static int port_cur;
+       struct pn_sock *pn = pn_sk(sk);
+       struct sockaddr_pn try_sa;
+       struct sock *tmpsk;
+
+       memset(&try_sa, 0, sizeof(struct sockaddr_pn));
+       try_sa.spn_family = AF_PHONET;
+
+       mutex_lock(&port_mutex);
+
+       if (!sport) {
+               /* search free port */
+               int port, pmin, pmax;
+
+               phonet_get_local_port_range(&pmin, &pmax);
+               for (port = pmin; port <= pmax; port++) {
+                       port_cur++;
+                       if (port_cur < pmin || port_cur > pmax)
+                               port_cur = pmin;
+
+                       pn_sockaddr_set_port(&try_sa, port_cur);
+                       tmpsk = pn_find_sock_by_sa(&try_sa);
+                       if (tmpsk == NULL) {
+                               sport = port_cur;
+                               goto found;
+                       } else
+                               sock_put(tmpsk);
+               }
+       } else {
+               /* try to find specific port */
+               pn_sockaddr_set_port(&try_sa, sport);
+               tmpsk = pn_find_sock_by_sa(&try_sa);
+               if (tmpsk == NULL)
+                       /* No sock there! We can use that port... */
+                       goto found;
+               else
+                       sock_put(tmpsk);
+       }
+       mutex_unlock(&port_mutex);
+
+       /* the port must be in use already */
+       return -EADDRINUSE;
+
+found:
+       mutex_unlock(&port_mutex);
+       pn->sobject = pn_object(pn_addr(pn->sobject), sport);
+       return 0;
+}
+EXPORT_SYMBOL(pn_sock_get_port);
diff --git a/net/phonet/sysctl.c b/net/phonet/sysctl.c
new file mode 100644 (file)
index 0000000..600a430
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * File: sysctl.c
+ *
+ * Phonet /proc/sys/net/phonet interface implementation
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include <linux/seqlock.h>
+#include <linux/sysctl.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#define DYNAMIC_PORT_MIN       0x40
+#define DYNAMIC_PORT_MAX       0x7f
+
+static DEFINE_SEQLOCK(local_port_range_lock);
+static int local_port_range_min[2] = {0, 0};
+static int local_port_range_max[2] = {1023, 1023};
+static int local_port_range[2] = {DYNAMIC_PORT_MIN, DYNAMIC_PORT_MAX};
+static struct ctl_table_header *phonet_table_hrd;
+
+static void set_local_port_range(int range[2])
+{
+       write_seqlock(&local_port_range_lock);
+       local_port_range[0] = range[0];
+       local_port_range[1] = range[1];
+       write_sequnlock(&local_port_range_lock);
+}
+
+void phonet_get_local_port_range(int *min, int *max)
+{
+       unsigned seq;
+       do {
+               seq = read_seqbegin(&local_port_range_lock);
+               if (min)
+                       *min = local_port_range[0];
+               if (max)
+                       *max = local_port_range[1];
+       } while (read_seqretry(&local_port_range_lock, seq));
+}
+
+static int proc_local_port_range(ctl_table *table, int write, struct file *filp,
+                               void __user *buffer,
+                               size_t *lenp, loff_t *ppos)
+{
+       int ret;
+       int range[2] = {local_port_range[0], local_port_range[1]};
+       ctl_table tmp = {
+               .data = &range,
+               .maxlen = sizeof(range),
+               .mode = table->mode,
+               .extra1 = &local_port_range_min,
+               .extra2 = &local_port_range_max,
+       };
+
+       ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
+
+       if (write && ret == 0) {
+               if (range[1] < range[0])
+                       ret = -EINVAL;
+               else
+                       set_local_port_range(range);
+       }
+
+       return ret;
+}
+
+static struct ctl_table phonet_table[] = {
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "local_port_range",
+               .data           = &local_port_range,
+               .maxlen         = sizeof(local_port_range),
+               .mode           = 0644,
+               .proc_handler   = &proc_local_port_range,
+               .strategy       = NULL,
+       },
+       { .ctl_name = 0 }
+};
+
+struct ctl_path phonet_ctl_path[] = {
+       { .procname = "net", .ctl_name = CTL_NET, },
+       { .procname = "phonet", .ctl_name = CTL_UNNUMBERED, },
+       { },
+};
+
+int __init phonet_sysctl_init(void)
+{
+       phonet_table_hrd = register_sysctl_paths(phonet_ctl_path, phonet_table);
+       return phonet_table_hrd == NULL ? -ENOMEM : 0;
+}
+
+void phonet_sysctl_exit(void)
+{
+       unregister_sysctl_table(phonet_table_hrd);
+}
index cc49c932641d97c66521c13b45fb4374792d8c4a..bc450397487ac7928620d5d63c95274c856b994a 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 #include <linux/tc_ematch/tc_em_cmp.h>
+#include <asm/unaligned.h>
 #include <net/pkt_cls.h>
 
 static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp)
@@ -37,8 +38,7 @@ static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
                        break;
 
                case TCF_EM_ALIGN_U16:
-                       val = *ptr << 8;
-                       val |= *(ptr+1);
+                       val = get_unaligned_be16(ptr);
 
                        if (cmp_needs_transformation(cmp))
                                val = be16_to_cpu(val);
@@ -47,10 +47,7 @@ static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
                case TCF_EM_ALIGN_U32:
                        /* Worth checking boundries? The branching seems
                         * to get worse. Visit again. */
-                       val = *ptr << 24;
-                       val |= *(ptr+1) << 16;
-                       val |= *(ptr+2) << 8;
-                       val |= *(ptr+3);
+                       val = get_unaligned_be32(ptr);
 
                        if (cmp_needs_transformation(cmp))
                                val = be32_to_cpu(val);
index ec0a0839ce512620231997be5f5c233b4bea423a..31f6b614b59be9ca66650995c704fbbd17632210 100644 (file)
@@ -44,23 +44,29 @@ static inline int qdisc_qlen(struct Qdisc *q)
 
 static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
 {
-       if (unlikely(skb->next))
-               q->gso_skb = skb;
-       else
-               q->ops->requeue(skb, q);
-
+       q->gso_skb = skb;
        __netif_schedule(q);
+
        return 0;
 }
 
 static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
 {
-       struct sk_buff *skb;
+       struct sk_buff *skb = q->gso_skb;
 
-       if ((skb = q->gso_skb))
-               q->gso_skb = NULL;
-       else
+       if (unlikely(skb)) {
+               struct net_device *dev = qdisc_dev(q);
+               struct netdev_queue *txq;
+
+               /* check the reason of requeuing without tx lock first */
+               txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
+               if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq))
+                       q->gso_skb = NULL;
+               else
+                       skb = NULL;
+       } else {
                skb = q->dequeue(q);
+       }
 
        return skb;
 }
@@ -327,6 +333,7 @@ struct Qdisc noop_qdisc = {
        .flags          =       TCQ_F_BUILTIN,
        .ops            =       &noop_qdisc_ops,
        .list           =       LIST_HEAD_INIT(noop_qdisc.list),
+       .requeue.lock   =       __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
        .q.lock         =       __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
        .dev_queue      =       &noop_netdev_queue,
 };
@@ -352,6 +359,7 @@ static struct Qdisc noqueue_qdisc = {
        .flags          =       TCQ_F_BUILTIN,
        .ops            =       &noqueue_qdisc_ops,
        .list           =       LIST_HEAD_INIT(noqueue_qdisc.list),
+       .requeue.lock   =       __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
        .q.lock         =       __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
        .dev_queue      =       &noqueue_netdev_queue,
 };
@@ -472,6 +480,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
        sch->padded = (char *) sch - (char *) p;
 
        INIT_LIST_HEAD(&sch->list);
+       skb_queue_head_init(&sch->requeue);
        skb_queue_head_init(&sch->q);
        sch->ops = ops;
        sch->enqueue = ops->enqueue;
@@ -540,6 +549,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
        dev_put(qdisc_dev(qdisc));
 
        kfree_skb(qdisc->gso_skb);
+       __skb_queue_purge(&qdisc->requeue);
 
        kfree((char *) qdisc - qdisc->padded);
 }
index 8472b8b349c464ac8a900d6b23241ce59efc5397..abd51cef24131846299485b6f238ecbd4c939dbe 100644 (file)
@@ -599,11 +599,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
        /* Check to see if this is a duplicate. */
        peer = sctp_assoc_lookup_paddr(asoc, addr);
        if (peer) {
+               /* An UNKNOWN state is only set on transports added by
+                * user in sctp_connectx() call.  Such transports should be
+                * considered CONFIRMED per RFC 4960, Section 5.4.
+                */
                if (peer->state == SCTP_UNKNOWN) {
-                       if (peer_state == SCTP_ACTIVE)
-                               peer->state = SCTP_ACTIVE;
-                       if (peer_state == SCTP_UNCONFIRMED)
-                               peer->state = SCTP_UNCONFIRMED;
+                       peer->state = SCTP_ACTIVE;
                }
                return peer;
        }
index f62bc24689353557c5f11232cdd0230c9598d6d4..6d5944a745d4e3d709ef2660389638d65882a1bc 100644 (file)
@@ -457,7 +457,7 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
 {
        int error = 0;
 
-       if (sctp_is_any(addr)) {
+       if (sctp_is_any(NULL, addr)) {
                error = sctp_copy_local_addr_list(dest, scope, gfp, flags);
        } else if (sctp_in_scope(addr, scope)) {
                /* Now that the address is in scope, check to see if
@@ -477,11 +477,21 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
 }
 
 /* Is this a wildcard address?  */
-int sctp_is_any(const union sctp_addr *addr)
+int sctp_is_any(struct sock *sk, const union sctp_addr *addr)
 {
-       struct sctp_af *af = sctp_get_af_specific(addr->sa.sa_family);
+       unsigned short fam = 0;
+       struct sctp_af *af;
+
+       /* Try to get the right address family */
+       if (addr->sa.sa_family != AF_UNSPEC)
+               fam = addr->sa.sa_family;
+       else if (sk)
+               fam = sk->sk_family;
+
+       af = sctp_get_af_specific(fam);
        if (!af)
                return 0;
+
        return af->is_any(addr);
 }
 
index 47f91afa02114229997f0f06810e156fcf9580fc..c78da3c9dd347ed16952d4ba98eb1341574dff7d 100644 (file)
@@ -837,6 +837,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
                               struct sctp_sock *opt)
 {
        struct sctp_af *af1, *af2;
+       struct sock *sk = sctp_opt2sk(opt);
 
        af1 = sctp_get_af_specific(addr1->sa.sa_family);
        af2 = sctp_get_af_specific(addr2->sa.sa_family);
@@ -845,11 +846,11 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
                return 0;
 
        /* If the socket is IPv6 only, v4 addrs will not match */
-       if (__ipv6_only_sock(sctp_opt2sk(opt)) && af1 != af2)
+       if (__ipv6_only_sock(sk) && af1 != af2)
                return 0;
 
        /* Today, wildcard AF_INET/AF_INET6. */
-       if (sctp_is_any(addr1) || sctp_is_any(addr2))
+       if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2))
                return 1;
 
        if (addr1->sa.sa_family != addr2->sa.sa_family)
index 0dc4a7dfb23443eacbe4accda160787443646906..c3f417f7ec6e8d305ae3e50ef7aa15fd33170080 100644 (file)
@@ -533,7 +533,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
        if (!(dst->dev->features & NETIF_F_NO_CSUM)) {
                crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
                crc32 = sctp_end_cksum(crc32);
-       }
+       } else
+               nskb->ip_summed = CHECKSUM_UNNECESSARY;
 
        /* 3) Put the resultant value into the checksum field in the
         *    common header, and leave the rest of the bits unchanged.
@@ -698,7 +699,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
         *    When a Fast Retransmit is being performed the sender SHOULD
         *    ignore the value of cwnd and SHOULD NOT delay retransmission.
         */
-       if (chunk->fast_retransmit <= 0)
+       if (chunk->fast_retransmit != SCTP_NEED_FRTX)
                if (transport->flight_size >= transport->cwnd) {
                        retval = SCTP_XMIT_RWND_FULL;
                        goto finish;
index 4328ad5439c9fa014f10cea4e9d17ab6b9ffbffd..247ebc95c1e59186ade6e76aec48fd3c57f7738c 100644 (file)
@@ -420,7 +420,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
                 * be added to the retransmit queue.
                 */
                if ((reason == SCTP_RTXR_FAST_RTX  &&
-                           (chunk->fast_retransmit > 0)) ||
+                           (chunk->fast_retransmit == SCTP_NEED_FRTX)) ||
                    (reason != SCTP_RTXR_FAST_RTX  && !chunk->tsn_gap_acked)) {
                        /* If this chunk was sent less then 1 rto ago, do not
                         * retransmit this chunk, but give the peer time
@@ -650,8 +650,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
                        /* Mark the chunk as ineligible for fast retransmit
                         * after it is retransmitted.
                         */
-                       if (chunk->fast_retransmit > 0)
-                               chunk->fast_retransmit = -1;
+                       if (chunk->fast_retransmit == SCTP_NEED_FRTX)
+                               chunk->fast_retransmit = SCTP_DONT_FRTX;
 
                        /* Force start T3-rtx timer when fast retransmitting
                         * the earliest outstanding TSN
@@ -680,8 +680,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
         */
        if (rtx_timeout || fast_rtx) {
                list_for_each_entry(chunk1, lqueue, transmitted_list) {
-                       if (chunk1->fast_retransmit > 0)
-                               chunk1->fast_retransmit = -1;
+                       if (chunk1->fast_retransmit == SCTP_NEED_FRTX)
+                               chunk1->fast_retransmit = SCTP_DONT_FRTX;
                }
        }
 
@@ -1129,12 +1129,13 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
        unsigned outstanding;
        struct sctp_transport *primary = asoc->peer.primary_path;
        int count_of_newacks = 0;
+       int gap_ack_blocks;
 
        /* Grab the association's destination address list. */
        transport_list = &asoc->peer.transport_addr_list;
 
        sack_ctsn = ntohl(sack->cum_tsn_ack);
-
+       gap_ack_blocks = ntohs(sack->num_gap_ack_blocks);
        /*
         * SFR-CACC algorithm:
         * On receipt of a SACK the sender SHOULD execute the
@@ -1144,35 +1145,38 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
         * on the current primary, the CHANGEOVER_ACTIVE flag SHOULD be
         * cleared. The CYCLING_CHANGEOVER flag SHOULD also be cleared for
         * all destinations.
-        */
-       if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) {
-               primary->cacc.changeover_active = 0;
-               list_for_each_entry(transport, transport_list,
-                               transports) {
-                       transport->cacc.cycling_changeover = 0;
-               }
-       }
-
-       /*
-        * SFR-CACC algorithm:
         * 2) If the SACK contains gap acks and the flag CHANGEOVER_ACTIVE
         * is set the receiver of the SACK MUST take the following actions:
         *
         * A) Initialize the cacc_saw_newack to 0 for all destination
         * addresses.
+        *
+        * Only bother if changeover_active is set. Otherwise, this is
+        * totally suboptimal to do on every SACK.
         */
-       if (sack->num_gap_ack_blocks &&
-           primary->cacc.changeover_active) {
-               list_for_each_entry(transport, transport_list, transports) {
-                       transport->cacc.cacc_saw_newack = 0;
+       if (primary->cacc.changeover_active) {
+               u8 clear_cycling = 0;
+
+               if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) {
+                       primary->cacc.changeover_active = 0;
+                       clear_cycling = 1;
+               }
+
+               if (clear_cycling || gap_ack_blocks) {
+                       list_for_each_entry(transport, transport_list,
+                                       transports) {
+                               if (clear_cycling)
+                                       transport->cacc.cycling_changeover = 0;
+                               if (gap_ack_blocks)
+                                       transport->cacc.cacc_saw_newack = 0;
+                       }
                }
        }
 
        /* Get the highest TSN in the sack. */
        highest_tsn = sack_ctsn;
-       if (sack->num_gap_ack_blocks)
-               highest_tsn +=
-                   ntohs(frags[ntohs(sack->num_gap_ack_blocks) - 1].gab.end);
+       if (gap_ack_blocks)
+               highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end);
 
        if (TSN_lt(asoc->highest_sacked, highest_tsn)) {
                highest_new_tsn = highest_tsn;
@@ -1181,11 +1185,11 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
                highest_new_tsn = sctp_highest_new_tsn(sack, asoc);
        }
 
+
        /* Run through the retransmit queue.  Credit bytes received
         * and free those chunks that we can.
         */
        sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn);
-       sctp_mark_missing(q, &q->retransmit, NULL, highest_new_tsn, 0);
 
        /* Run through the transmitted queue.
         * Credit bytes received and free those chunks which we can.
@@ -1204,9 +1208,10 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
                        count_of_newacks ++;
        }
 
-       list_for_each_entry(transport, transport_list, transports) {
-               sctp_mark_missing(q, &transport->transmitted, transport,
-                                 highest_new_tsn, count_of_newacks);
+       if (gap_ack_blocks) {
+               list_for_each_entry(transport, transport_list, transports)
+                       sctp_mark_missing(q, &transport->transmitted, transport,
+                                         highest_new_tsn, count_of_newacks);
        }
 
        /* Move the Cumulative TSN Ack Point if appropriate.  */
@@ -1651,7 +1656,7 @@ static void sctp_mark_missing(struct sctp_outq *q,
                 * chunk if it has NOT been fast retransmitted or marked for
                 * fast retransmit already.
                 */
-               if (!chunk->fast_retransmit &&
+               if (chunk->fast_retransmit == SCTP_CAN_FRTX &&
                    !chunk->tsn_gap_acked &&
                    TSN_lt(tsn, highest_new_tsn_in_sack)) {
 
@@ -1676,7 +1681,7 @@ static void sctp_mark_missing(struct sctp_outq *q,
                 */
 
                if (chunk->tsn_missing_report >= 3) {
-                       chunk->fast_retransmit = 1;
+                       chunk->fast_retransmit = SCTP_NEED_FRTX;
                        do_fast_retransmit = 1;
                }
        }
index e8ca4e54981fb16d9e03790a8fcccd55002f660d..76726bcff3e9b4a4cc599ff3dc85edfb51e84e2a 100644 (file)
@@ -1012,6 +1012,29 @@ end:
        return retval;
 }
 
+struct sctp_chunk *sctp_make_violation_paramlen(
+       const struct sctp_association *asoc,
+       const struct sctp_chunk *chunk,
+       struct sctp_paramhdr *param)
+{
+       struct sctp_chunk *retval;
+       static const char error[] = "The following parameter had invalid length:";
+       size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) +
+                               sizeof(sctp_paramhdr_t);
+
+       retval = sctp_make_abort(asoc, chunk, payload_len);
+       if (!retval)
+               goto nodata;
+
+       sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION,
+                       sizeof(error) + sizeof(sctp_paramhdr_t));
+       sctp_addto_chunk(retval, sizeof(error), error);
+       sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param);
+
+nodata:
+       return retval;
+}
+
 /* Make a HEARTBEAT chunk.  */
 struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
                                  const struct sctp_transport *transport,
@@ -1188,7 +1211,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
         */
        retval->tsn_missing_report = 0;
        retval->tsn_gap_acked = 0;
-       retval->fast_retransmit = 0;
+       retval->fast_retransmit = SCTP_CAN_FRTX;
 
        /* If this is a fragmented message, track all fragments
         * of the message (for SEND_FAILED).
@@ -1782,11 +1805,6 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
                                        const struct sctp_chunk *chunk,
                                        struct sctp_chunk **errp)
 {
-       static const char error[] = "The following parameter had invalid length:";
-       size_t          payload_len = WORD_ROUND(sizeof(error)) +
-                                               sizeof(sctp_paramhdr_t);
-
-
        /* This is a fatal error.  Any accumulated non-fatal errors are
         * not reported.
         */
@@ -1794,14 +1812,7 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
                sctp_chunk_free(*errp);
 
        /* Create an error chunk and fill it in with our payload. */
-       *errp = sctp_make_op_error_space(asoc, chunk, payload_len);
-
-       if (*errp) {
-               sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
-                               sizeof(error) + sizeof(sctp_paramhdr_t));
-               sctp_addto_chunk(*errp, sizeof(error), error);
-               sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param);
-       }
+       *errp = sctp_make_violation_paramlen(asoc, chunk, param);
 
        return 0;
 }
@@ -1886,11 +1897,13 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
                            /* if the peer reports AUTH, assume that he
                             * supports AUTH.
                             */
-                           asoc->peer.auth_capable = 1;
+                           if (sctp_auth_enable)
+                                   asoc->peer.auth_capable = 1;
                            break;
                    case SCTP_CID_ASCONF:
                    case SCTP_CID_ASCONF_ACK:
-                           asoc->peer.asconf_capable = 1;
+                           if (sctp_addip_enable)
+                                   asoc->peer.asconf_capable = 1;
                            break;
                    default:
                            break;
@@ -2319,12 +2332,10 @@ clean_up:
        /* Release the transport structures. */
        list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
                transport = list_entry(pos, struct sctp_transport, transports);
-               list_del_init(pos);
-               sctp_transport_free(transport);
+               if (transport->state != SCTP_ACTIVE)
+                       sctp_assoc_rm_peer(asoc, transport);
        }
 
-       asoc->peer.transport_count = 0;
-
 nomem:
        return 0;
 }
@@ -2456,10 +2467,13 @@ do_addr_param:
                break;
 
        case SCTP_PARAM_ADAPTATION_LAYER_IND:
-               asoc->peer.adaptation_ind = param.aind->adaptation_ind;
+               asoc->peer.adaptation_ind = ntohl(param.aind->adaptation_ind);
                break;
 
        case SCTP_PARAM_SET_PRIMARY:
+               if (!sctp_addip_enable)
+                       goto fall_through;
+
                addr_param = param.v + sizeof(sctp_addip_param_t);
 
                af = sctp_get_af_specific(param_type2af(param.p->type));
index 9732c797e8edf06d73e69088d044b4af9ac3e236..13d9eea5cf1a9b25258f60b1f9afeb7a80b9359e 100644 (file)
@@ -889,6 +889,35 @@ static void sctp_cmd_adaptation_ind(sctp_cmd_seq_t *commands,
                sctp_ulpq_tail_event(&asoc->ulpq, ev);
 }
 
+
+static void sctp_cmd_t1_timer_update(struct sctp_association *asoc,
+                                   sctp_event_timeout_t timer,
+                                   char *name)
+{
+       struct sctp_transport *t;
+
+       t = asoc->init_last_sent_to;
+       asoc->init_err_counter++;
+
+       if (t->init_sent_count > (asoc->init_cycle + 1)) {
+               asoc->timeouts[timer] *= 2;
+               if (asoc->timeouts[timer] > asoc->max_init_timeo) {
+                       asoc->timeouts[timer] = asoc->max_init_timeo;
+               }
+               asoc->init_cycle++;
+               SCTP_DEBUG_PRINTK(
+                       "T1 %s Timeout adjustment"
+                       " init_err_counter: %d"
+                       " cycle: %d"
+                       " timeout: %ld\n",
+                       name,
+                       asoc->init_err_counter,
+                       asoc->init_cycle,
+                       asoc->timeouts[timer]);
+       }
+
+}
+
 /* These three macros allow us to pull the debugging code out of the
  * main flow of sctp_do_sm() to keep attention focused on the real
  * functionality there.
@@ -1196,6 +1225,11 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
                                                SCTP_CHUNK(cmd->obj.ptr));
 
+                       if (new_obj->transport) {
+                               new_obj->transport->init_sent_count++;
+                               asoc->init_last_sent_to = new_obj->transport;
+                       }
+
                        /* FIXME - Eventually come up with a cleaner way to
                         * enabling COOKIE-ECHO + DATA bundling during
                         * multihoming stale cookie scenarios, the following
@@ -1345,26 +1379,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                         * all transports have been tried at the current
                         * timeout.
                         */
-                       t = asoc->init_last_sent_to;
-                       asoc->init_err_counter++;
-
-                       if (t->init_sent_count > (asoc->init_cycle + 1)) {
-                               asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] *= 2;
-                               if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] >
-                                   asoc->max_init_timeo) {
-                                       asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
-                                               asoc->max_init_timeo;
-                               }
-                               asoc->init_cycle++;
-                               SCTP_DEBUG_PRINTK(
-                                       "T1 INIT Timeout adjustment"
-                                       " init_err_counter: %d"
-                                       " cycle: %d"
-                                       " timeout: %ld\n",
-                                       asoc->init_err_counter,
-                                       asoc->init_cycle,
-                                       asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
-                       }
+                       sctp_cmd_t1_timer_update(asoc,
+                                               SCTP_EVENT_TIMEOUT_T1_INIT,
+                                               "INIT");
 
                        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
                                        SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
@@ -1377,20 +1394,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                         * all transports have been tried at the current
                         * timeout.
                         */
-                       asoc->init_err_counter++;
-
-                       asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] *= 2;
-                       if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] >
-                           asoc->max_init_timeo) {
-                               asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
-                                       asoc->max_init_timeo;
-                       }
-                       SCTP_DEBUG_PRINTK(
-                               "T1 COOKIE Timeout adjustment"
-                               " init_err_counter: %d"
-                               " timeout: %ld\n",
-                               asoc->init_err_counter,
-                               asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
+                       sctp_cmd_t1_timer_update(asoc,
+                                               SCTP_EVENT_TIMEOUT_T1_COOKIE,
+                                               "COOKIE");
 
                        /* If we've sent any data bundled with
                         * COOKIE-ECHO we need to resend.
@@ -1422,6 +1428,10 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                case SCTP_CMD_INIT_COUNTER_RESET:
                        asoc->init_err_counter = 0;
                        asoc->init_cycle = 0;
+                       list_for_each_entry(t, &asoc->peer.transport_addr_list,
+                                           transports) {
+                               t->init_sent_count = 0;
+                       }
                        break;
 
                case SCTP_CMD_REPORT_DUP:
index 8848d329aa2cea8bea3e3aec60405a4af51767cb..ea3a34cbe47001008553658ebaa987fbcb568dc3 100644 (file)
@@ -119,7 +119,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
                                     const struct sctp_endpoint *ep,
                                     const struct sctp_association *asoc,
                                     const sctp_subtype_t type,
-                                    void *arg,
+                                    void *arg, void *ext,
                                     sctp_cmd_seq_t *commands);
 
 static sctp_disposition_t sctp_sf_violation_ctsn(
@@ -315,8 +315,10 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
        /* If the packet is an OOTB packet which is temporarily on the
         * control endpoint, respond with an ABORT.
         */
-       if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
+       if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) {
+               SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
                return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+       }
 
        /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
         * Tag.
@@ -635,8 +637,10 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
        /* If the packet is an OOTB packet which is temporarily on the
         * control endpoint, respond with an ABORT.
         */
-       if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
+       if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) {
+               SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
                return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
+       }
 
        /* Make sure that the COOKIE_ECHO chunk has a valid length.
         * In this case, we check that we have enough for at least a
@@ -2076,10 +2080,6 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
                    sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
                return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
 
-       /* Stop the T5-shutdown guard timer.  */
-       sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
-                       SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
-
        return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
 }
 
@@ -3382,6 +3382,8 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
         * packet and the state function that handles OOTB SHUTDOWN_ACK is
         * called with a NULL association.
         */
+       SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
+
        return sctp_sf_shut_8_4_5(ep, NULL, type, arg, commands);
 }
 
@@ -3425,7 +3427,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
        addr_param = (union sctp_addr_param *)hdr->params;
        length = ntohs(addr_param->p.length);
        if (length < sizeof(sctp_paramhdr_t))
-               return sctp_sf_violation_paramlen(ep, asoc, type,
+               return sctp_sf_violation_paramlen(ep, asoc, type, arg,
                           (void *)addr_param, commands);
 
        /* Verify the ASCONF chunk before processing it. */
@@ -3433,8 +3435,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
                            (sctp_paramhdr_t *)((void *)addr_param + length),
                            (void *)chunk->chunk_end,
                            &err_param))
-               return sctp_sf_violation_paramlen(ep, asoc, type,
-                                                 (void *)&err_param, commands);
+               return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+                                                 (void *)err_param, commands);
 
        /* ADDIP 5.2 E1) Compare the value of the serial number to the value
         * the endpoint stored in a new association variable
@@ -3542,8 +3544,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
            (sctp_paramhdr_t *)addip_hdr->params,
            (void *)asconf_ack->chunk_end,
            &err_param))
-               return sctp_sf_violation_paramlen(ep, asoc, type,
-                          (void *)&err_param, commands);
+               return sctp_sf_violation_paramlen(ep, asoc, type, arg,
+                          (void *)err_param, commands);
 
        if (last_asconf) {
                addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr;
@@ -4240,12 +4242,38 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
                                     const struct sctp_endpoint *ep,
                                     const struct sctp_association *asoc,
                                     const sctp_subtype_t type,
-                                    void *arg,
-                                    sctp_cmd_seq_t *commands) {
-       static const char err_str[] = "The following parameter had invalid length:";
+                                    void *arg, void *ext,
+                                    sctp_cmd_seq_t *commands)
+{
+       struct sctp_chunk *chunk =  arg;
+       struct sctp_paramhdr *param = ext;
+       struct sctp_chunk *abort = NULL;
 
-       return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
-                                       sizeof(err_str));
+       if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
+               goto discard;
+
+       /* Make the abort chunk. */
+       abort = sctp_make_violation_paramlen(asoc, chunk, param);
+       if (!abort)
+               goto nomem;
+
+       sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
+       SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
+
+       sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
+                       SCTP_ERROR(ECONNABORTED));
+       sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
+                       SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
+       SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
+
+discard:
+       sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
+
+       SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
+
+       return SCTP_DISPOSITION_ABORT;
+nomem:
+       return SCTP_DISPOSITION_NOMEM;
 }
 
 /* Handle a protocol violation when the peer trying to advance the
@@ -4517,13 +4545,6 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
 
-       /* sctpimpguide-05 Section 2.12.2
-        * The sender of the SHUTDOWN MAY also start an overall guard timer
-        * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
-        */
-       sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
-                       SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
-
        disposition = SCTP_DISPOSITION_CONSUME;
        if (sctp_outq_is_empty(&asoc->outqueue)) {
                disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
@@ -4968,6 +4989,13 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
        sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
                        SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
 
+       /* RFC 4960 Section 9.2
+        * The sender of the SHUTDOWN MAY also start an overall guard timer
+        * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
+        */
+       sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
+                       SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
+
        if (asoc->autoclose)
                sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
@@ -5279,6 +5307,8 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep
                if (!repl)
                        return SCTP_DISPOSITION_NOMEM;
 
+               sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
+                               SCTP_CHUNK(repl));
                /* Issue a sideeffect to do the needed accounting. */
                sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART,
                                SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
@@ -5494,12 +5524,6 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire(
        sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
                        SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
 
-       /* sctpimpguide-05 Section 2.12.2
-        * The sender of the SHUTDOWN MAY also start an overall guard timer
-        * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
-        */
-       sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
-                       SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
        disposition = SCTP_DISPOSITION_CONSUME;
        if (sctp_outq_is_empty(&asoc->outqueue)) {
                disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
index d991237fb4003dd4a9cf9b2af454d5db1644ebe9..dd4ddc40c0ad86b0b0321be2613aa10af9222f43 100644 (file)
@@ -897,7 +897,7 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
        /* SCTP_STATE_ESTABLISHED */ \
        TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
        /* SCTP_STATE_SHUTDOWN_PENDING */ \
-       TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
+       TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
        /* SCTP_STATE_SHUTDOWN_SENT */ \
        TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
        /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
index 5ffb9dec1c3f17526a5c4474e086a2cd04c2a588..a1b904529d5e1c3e12ba0a6c1ff7bfbc2b5dbddb 100644 (file)
@@ -2309,7 +2309,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
        /* If an address other than INADDR_ANY is specified, and
         * no transport is found, then the request is invalid.
         */
-       if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) {
+       if (!sctp_is_any(sk, ( union sctp_addr *)&params.spp_address)) {
                trans = sctp_addr_id2transport(sk, &params.spp_address,
                                               params.spp_assoc_id);
                if (!trans)
@@ -4062,7 +4062,7 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
        /* If an address other than INADDR_ANY is specified, and
         * no transport is found, then the request is invalid.
         */
-       if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) {
+       if (!sctp_is_any(sk, ( union sctp_addr *)&params.spp_address)) {
                trans = sctp_addr_id2transport(sk, &params.spp_address,
                                               params.spp_assoc_id);
                if (!trans) {
@@ -4414,7 +4414,7 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
        if (sctp_list_single_entry(&bp->address_list)) {
                addr = list_entry(bp->address_list.next,
                                  struct sctp_sockaddr_entry, list);
-               if (sctp_is_any(&addr->a)) {
+               if (sctp_is_any(sk, &addr->a)) {
                        rcu_read_lock();
                        list_for_each_entry_rcu(addr,
                                                &sctp_local_addr_list, list) {
@@ -4602,7 +4602,7 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
        if (sctp_list_single_entry(&bp->address_list)) {
                addr = list_entry(bp->address_list.next,
                                  struct sctp_sockaddr_entry, list);
-               if (sctp_is_any(&addr->a)) {
+               if (sctp_is_any(sk, &addr->a)) {
                        cnt = sctp_copy_laddrs_old(sk, bp->port,
                                                   getaddrs.addr_num,
                                                   addrs, &bytes_copied);
@@ -4695,7 +4695,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
        if (sctp_list_single_entry(&bp->address_list)) {
                addr = list_entry(bp->address_list.next,
                                  struct sctp_sockaddr_entry, list);
-               if (sctp_is_any(&addr->a)) {
+               if (sctp_is_any(sk, &addr->a)) {
                        cnt = sctp_copy_laddrs(sk, bp->port, addrs,
                                                space_left, &bytes_copied);
                        if (cnt < 0) {
index 5061a26c5028d927bf40bb51d772fe91691432f4..7b23803343cc66e39c6b6214d9b96ff2a0d4877a 100644 (file)
@@ -317,7 +317,7 @@ static void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq,
        }
 
        /* Insert before pos. */
-       __skb_insert(sctp_event2skb(event), pos->prev, pos, &ulpq->reasm);
+       __skb_queue_before(&ulpq->reasm, pos, sctp_event2skb(event));
 
 }
 
@@ -825,8 +825,7 @@ static void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq,
 
 
        /* Insert before pos. */
-       __skb_insert(sctp_event2skb(event), pos->prev, pos, &ulpq->lobby);
-
+       __skb_queue_before(&ulpq->lobby, pos, sctp_event2skb(event));
 }
 
 static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
index 8ef8ba81b9e2048c93363f4a2f98f73b7778cdce..3e8d4e35c08f3892e615959f60b0855e72f348a1 100644 (file)
@@ -1511,6 +1511,7 @@ out_fd:
        goto out_put;
 }
 
+#if 0
 #ifdef HAVE_SET_RESTORE_SIGMASK
 asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
                            int __user *upeer_addrlen,
@@ -1564,6 +1565,7 @@ asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
        return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
 }
 #endif
+#endif
 
 asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
                           int __user *upeer_addrlen)
index a910cd2d0fd113afce4d5afaba1a089bfa738448..5cadbeb76a1430ca30d0b1faff578f83807057e5 100644 (file)
@@ -29,113 +29,11 @@ MODULE_AUTHOR("Johannes Berg");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("wireless configuration support");
 
-struct list_head regulatory_requests;
-
-/* Central wireless core regulatory domains, we only need two,
- * the current one and a world regulatory domain in case we have no
- * information to give us an alpha2 */
-struct ieee80211_regdomain *cfg80211_regdomain;
-
-/* We keep a static world regulatory domain in case of the absence of CRDA */
-const struct ieee80211_regdomain world_regdom = {
-       .n_reg_rules = 1,
-       .alpha2 =  "00",
-       .reg_rules = {
-               REG_RULE(2402, 2472, 40, 6, 20,
-                       NL80211_RRF_PASSIVE_SCAN |
-                       NL80211_RRF_NO_IBSS),
-       }
-};
-
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-/* All this fucking static junk will be removed soon, so
- * don't fucking count on it !@#$ */
-
-static char *ieee80211_regdom = "US";
-module_param(ieee80211_regdom, charp, 0444);
-MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
-
-/* We assume 40 MHz bandwidth for the old regulatory work.
- * We make emphasis we are using the exact same frequencies
- * as before */
-
-const struct ieee80211_regdomain us_regdom = {
-       .n_reg_rules = 6,
-       .alpha2 =  "US",
-       .reg_rules = {
-               /* IEEE 802.11b/g, channels 1..11 */
-               REG_RULE(2412-20, 2462+20, 40, 6, 27, 0),
-               /* IEEE 802.11a, channel 36 */
-               REG_RULE(5180-20, 5180+20, 40, 6, 23, 0),
-               /* IEEE 802.11a, channel 40 */
-               REG_RULE(5200-20, 5200+20, 40, 6, 23, 0),
-               /* IEEE 802.11a, channel 44 */
-               REG_RULE(5220-20, 5220+20, 40, 6, 23, 0),
-               /* IEEE 802.11a, channels 48..64 */
-               REG_RULE(5240-20, 5320+20, 40, 6, 23, 0),
-               /* IEEE 802.11a, channels 149..165, outdoor */
-               REG_RULE(5745-20, 5825+20, 40, 6, 30, 0),
-       }
-};
-
-const struct ieee80211_regdomain jp_regdom = {
-       .n_reg_rules = 3,
-       .alpha2 =  "JP",
-       .reg_rules = {
-               /* IEEE 802.11b/g, channels 1..14 */
-               REG_RULE(2412-20, 2484+20, 40, 6, 20, 0),
-               /* IEEE 802.11a, channels 34..48 */
-               REG_RULE(5170-20, 5240+20, 40, 6, 20,
-                       NL80211_RRF_PASSIVE_SCAN),
-               /* IEEE 802.11a, channels 52..64 */
-               REG_RULE(5260-20, 5320+20, 40, 6, 20,
-                       NL80211_RRF_NO_IBSS |
-                       NL80211_RRF_DFS),
-       }
-};
-
-const struct ieee80211_regdomain eu_regdom = {
-       .n_reg_rules = 6,
-       /* This alpha2 is bogus, we leave it here just for stupid
-        * backward compatibility */
-       .alpha2 =  "EU",
-       .reg_rules = {
-               /* IEEE 802.11b/g, channels 1..13 */
-               REG_RULE(2412-20, 2472+20, 40, 6, 20, 0),
-               /* IEEE 802.11a, channel 36 */
-               REG_RULE(5180-20, 5180+20, 40, 6, 23,
-                       NL80211_RRF_PASSIVE_SCAN),
-               /* IEEE 802.11a, channel 40 */
-               REG_RULE(5200-20, 5200+20, 40, 6, 23,
-                       NL80211_RRF_PASSIVE_SCAN),
-               /* IEEE 802.11a, channel 44 */
-               REG_RULE(5220-20, 5220+20, 40, 6, 23,
-                       NL80211_RRF_PASSIVE_SCAN),
-               /* IEEE 802.11a, channels 48..64 */
-               REG_RULE(5240-20, 5320+20, 40, 6, 20,
-                       NL80211_RRF_NO_IBSS |
-                       NL80211_RRF_DFS),
-               /* IEEE 802.11a, channels 100..140 */
-               REG_RULE(5500-20, 5700+20, 40, 6, 30,
-                       NL80211_RRF_NO_IBSS |
-                       NL80211_RRF_DFS),
-       }
-};
-
-#endif
-
-struct ieee80211_regdomain *cfg80211_world_regdom =
-       (struct ieee80211_regdomain *) &world_regdom;
-
-LIST_HEAD(regulatory_requests);
-DEFINE_MUTEX(cfg80211_reg_mutex);
-
 /* RCU might be appropriate here since we usually
  * only read the list, and that can happen quite
  * often because we need to do it for each command */
 LIST_HEAD(cfg80211_drv_list);
 DEFINE_MUTEX(cfg80211_drv_mutex);
-static int wiphy_counter;
 
 /* for debugfs */
 static struct dentry *ieee80211_debugfs_dir;
@@ -307,6 +205,8 @@ out_unlock:
 
 struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
 {
+       static int wiphy_counter;
+
        struct cfg80211_registered_device *drv;
        int alloc_size;
 
@@ -323,21 +223,18 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
 
        mutex_lock(&cfg80211_drv_mutex);
 
-       drv->idx = wiphy_counter;
-
-       /* now increase counter for the next device unless
-        * it has wrapped previously */
-       if (wiphy_counter >= 0)
-               wiphy_counter++;
-
-       mutex_unlock(&cfg80211_drv_mutex);
+       drv->idx = wiphy_counter++;
 
        if (unlikely(drv->idx < 0)) {
+               wiphy_counter--;
+               mutex_unlock(&cfg80211_drv_mutex);
                /* ugh, wrapped! */
                kfree(drv);
                return NULL;
        }
 
+       mutex_unlock(&cfg80211_drv_mutex);
+
        /* give it a proper name */
        snprintf(drv->wiphy.dev.bus_id, BUS_ID_SIZE,
                 PHY_NAME "%d", drv->idx);
@@ -485,6 +382,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
 
        rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
 
+       WARN_ON(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_UNSPECIFIED);
+
        switch (state) {
        case NETDEV_REGISTER:
                mutex_lock(&rdev->devlist_mtx);
@@ -514,34 +413,10 @@ static struct notifier_block cfg80211_netdev_notifier = {
        .notifier_call = cfg80211_netdev_notifier_call,
 };
 
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-const struct ieee80211_regdomain *static_regdom(char *alpha2)
-{
-       if (alpha2[0] == 'U' && alpha2[1] == 'S')
-               return &us_regdom;
-       if (alpha2[0] == 'J' && alpha2[1] == 'P')
-               return &jp_regdom;
-       if (alpha2[0] == 'E' && alpha2[1] == 'U')
-               return &eu_regdom;
-       /* Default, as per the old rules */
-       return &us_regdom;
-}
-#endif
-
 static int cfg80211_init(void)
 {
        int err;
 
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-       cfg80211_regdomain =
-               (struct ieee80211_regdomain *) static_regdom(ieee80211_regdom);
-       /* Used during reset_regdomains_static() */
-       cfg80211_world_regdom = cfg80211_regdomain;
-#else
-       cfg80211_regdomain =
-               (struct ieee80211_regdomain *) cfg80211_world_regdom;
-#endif
-
        err = wiphy_sysfs_init();
        if (err)
                goto out_fail_sysfs;
@@ -560,25 +435,6 @@ static int cfg80211_init(void)
        if (err)
                goto out_fail_reg;
 
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-       printk(KERN_INFO "cfg80211: Using old static regulatory domain:\n");
-       print_regdomain_info(cfg80211_regdomain);
-       /* The old code still requests for a new regdomain and if
-        * you have CRDA you get it updated, otherwise you get
-        * stuck with the static values. We ignore "EU" code as
-        * that is not a valid ISO / IEC 3166 alpha2 */
-       if (ieee80211_regdom[0] != 'E' &&
-                       ieee80211_regdom[1] != 'U')
-               err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE,
-                       ieee80211_regdom, NULL);
-#else
-       err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", NULL);
-       if (err)
-               printk(KERN_ERR "cfg80211: calling CRDA failed - "
-                       "unable to update world regulatory domain, "
-                       "using static definition\n");
-#endif
-
        return 0;
 
 out_fail_reg:
index 1221d726ed50024a3ff0397bfec13371915a27ab..572793c8c7ab6b576dae03753b69503ee05f04cf 100644 (file)
@@ -299,7 +299,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
        NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
-       /* TODO: interface type */
+       NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
        return genlmsg_end(msg, hdr);
 
  nla_put_failure:
@@ -418,41 +418,56 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
        int err, ifindex;
        enum nl80211_iftype type;
        struct net_device *dev;
-       u32 flags;
+       u32 _flags, *flags = NULL;
 
        memset(&params, 0, sizeof(params));
 
-       if (info->attrs[NL80211_ATTR_IFTYPE]) {
-               type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
-               if (type > NL80211_IFTYPE_MAX)
-                       return -EINVAL;
-       } else
-               return -EINVAL;
-
        err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
        if (err)
                return err;
        ifindex = dev->ifindex;
+       type = dev->ieee80211_ptr->iftype;
        dev_put(dev);
 
+       err = -EINVAL;
+       if (info->attrs[NL80211_ATTR_IFTYPE]) {
+               type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
+               if (type > NL80211_IFTYPE_MAX)
+                       goto unlock;
+       }
+
        if (!drv->ops->change_virtual_intf ||
            !(drv->wiphy.interface_modes & (1 << type))) {
                err = -EOPNOTSUPP;
                goto unlock;
        }
 
-       if (type == NL80211_IFTYPE_MESH_POINT &&
-           info->attrs[NL80211_ATTR_MESH_ID]) {
+       if (info->attrs[NL80211_ATTR_MESH_ID]) {
+               if (type != NL80211_IFTYPE_MESH_POINT) {
+                       err = -EINVAL;
+                       goto unlock;
+               }
                params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
                params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
        }
 
+       if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
+               if (type != NL80211_IFTYPE_MONITOR) {
+                       err = -EINVAL;
+                       goto unlock;
+               }
+               err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
+                                         &_flags);
+               if (!err)
+                       flags = &_flags;
+       }
        rtnl_lock();
-       err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
-                                 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
-                                 &flags);
        err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
-                                           type, err ? NULL : &flags, &params);
+                                           type, flags, &params);
+
+       dev = __dev_get_by_index(&init_net, ifindex);
+       WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
+
        rtnl_unlock();
 
  unlock:
index 592b2e391d42085686dc3a461b7bae61c05cc5d2..626dbb688499bd9dafa0b963305df65d3ac0c04a 100644 (file)
 #include "core.h"
 #include "reg.h"
 
+/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
+struct regulatory_request {
+       struct list_head list;
+       struct wiphy *wiphy;
+       int granted;
+       enum reg_set_by initiator;
+       char alpha2[2];
+};
+
+static LIST_HEAD(regulatory_requests);
+DEFINE_MUTEX(cfg80211_reg_mutex);
+
 /* To trigger userspace events */
 static struct platform_device *reg_pdev;
 
@@ -51,7 +63,156 @@ static u32 supported_bandwidths[] = {
        MHZ_TO_KHZ(20),
 };
 
-bool is_world_regdom(char *alpha2)
+static struct list_head regulatory_requests;
+
+/* Central wireless core regulatory domains, we only need two,
+ * the current one and a world regulatory domain in case we have no
+ * information to give us an alpha2 */
+static const struct ieee80211_regdomain *cfg80211_regdomain;
+
+/* We keep a static world regulatory domain in case of the absence of CRDA */
+static const struct ieee80211_regdomain world_regdom = {
+       .n_reg_rules = 1,
+       .alpha2 =  "00",
+       .reg_rules = {
+               REG_RULE(2412-10, 2462+10, 40, 6, 20,
+                       NL80211_RRF_PASSIVE_SCAN |
+                       NL80211_RRF_NO_IBSS),
+       }
+};
+
+static const struct ieee80211_regdomain *cfg80211_world_regdom =
+       &world_regdom;
+
+#ifdef CONFIG_WIRELESS_OLD_REGULATORY
+static char *ieee80211_regdom = "US";
+module_param(ieee80211_regdom, charp, 0444);
+MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
+
+/* We assume 40 MHz bandwidth for the old regulatory work.
+ * We make emphasis we are using the exact same frequencies
+ * as before */
+
+static const struct ieee80211_regdomain us_regdom = {
+       .n_reg_rules = 6,
+       .alpha2 =  "US",
+       .reg_rules = {
+               /* IEEE 802.11b/g, channels 1..11 */
+               REG_RULE(2412-10, 2462+10, 40, 6, 27, 0),
+               /* IEEE 802.11a, channel 36 */
+               REG_RULE(5180-10, 5180+10, 40, 6, 23, 0),
+               /* IEEE 802.11a, channel 40 */
+               REG_RULE(5200-10, 5200+10, 40, 6, 23, 0),
+               /* IEEE 802.11a, channel 44 */
+               REG_RULE(5220-10, 5220+10, 40, 6, 23, 0),
+               /* IEEE 802.11a, channels 48..64 */
+               REG_RULE(5240-10, 5320+10, 40, 6, 23, 0),
+               /* IEEE 802.11a, channels 149..165, outdoor */
+               REG_RULE(5745-10, 5825+10, 40, 6, 30, 0),
+       }
+};
+
+static const struct ieee80211_regdomain jp_regdom = {
+       .n_reg_rules = 3,
+       .alpha2 =  "JP",
+       .reg_rules = {
+               /* IEEE 802.11b/g, channels 1..14 */
+               REG_RULE(2412-10, 2484+10, 40, 6, 20, 0),
+               /* IEEE 802.11a, channels 34..48 */
+               REG_RULE(5170-10, 5240+10, 40, 6, 20,
+                       NL80211_RRF_PASSIVE_SCAN),
+               /* IEEE 802.11a, channels 52..64 */
+               REG_RULE(5260-10, 5320+10, 40, 6, 20,
+                       NL80211_RRF_NO_IBSS |
+                       NL80211_RRF_DFS),
+       }
+};
+
+static const struct ieee80211_regdomain eu_regdom = {
+       .n_reg_rules = 6,
+       /* This alpha2 is bogus, we leave it here just for stupid
+        * backward compatibility */
+       .alpha2 =  "EU",
+       .reg_rules = {
+               /* IEEE 802.11b/g, channels 1..13 */
+               REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
+               /* IEEE 802.11a, channel 36 */
+               REG_RULE(5180-10, 5180+10, 40, 6, 23,
+                       NL80211_RRF_PASSIVE_SCAN),
+               /* IEEE 802.11a, channel 40 */
+               REG_RULE(5200-10, 5200+10, 40, 6, 23,
+                       NL80211_RRF_PASSIVE_SCAN),
+               /* IEEE 802.11a, channel 44 */
+               REG_RULE(5220-10, 5220+10, 40, 6, 23,
+                       NL80211_RRF_PASSIVE_SCAN),
+               /* IEEE 802.11a, channels 48..64 */
+               REG_RULE(5240-10, 5320+10, 40, 6, 20,
+                       NL80211_RRF_NO_IBSS |
+                       NL80211_RRF_DFS),
+               /* IEEE 802.11a, channels 100..140 */
+               REG_RULE(5500-10, 5700+10, 40, 6, 30,
+                       NL80211_RRF_NO_IBSS |
+                       NL80211_RRF_DFS),
+       }
+};
+
+static const struct ieee80211_regdomain *static_regdom(char *alpha2)
+{
+       if (alpha2[0] == 'U' && alpha2[1] == 'S')
+               return &us_regdom;
+       if (alpha2[0] == 'J' && alpha2[1] == 'P')
+               return &jp_regdom;
+       if (alpha2[0] == 'E' && alpha2[1] == 'U')
+               return &eu_regdom;
+       /* Default, as per the old rules */
+       return &us_regdom;
+}
+
+static bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
+{
+       if (rd == &us_regdom || rd == &jp_regdom || rd == &eu_regdom)
+               return true;
+       return false;
+}
+#else
+static inline bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
+{
+       return false;
+}
+#endif
+
+static void reset_regdomains(void)
+{
+       /* avoid freeing static information or freeing something twice */
+       if (cfg80211_regdomain == cfg80211_world_regdom)
+               cfg80211_regdomain = NULL;
+       if (cfg80211_world_regdom == &world_regdom)
+               cfg80211_world_regdom = NULL;
+       if (cfg80211_regdomain == &world_regdom)
+               cfg80211_regdomain = NULL;
+       if (is_old_static_regdom(cfg80211_regdomain))
+               cfg80211_regdomain = NULL;
+
+       kfree(cfg80211_regdomain);
+       kfree(cfg80211_world_regdom);
+
+       cfg80211_world_regdom = &world_regdom;
+       cfg80211_regdomain = NULL;
+}
+
+/* Dynamic world regulatory domain requested by the wireless
+ * core upon initialization */
+static void update_world_regdomain(const struct ieee80211_regdomain *rd)
+{
+       BUG_ON(list_empty(&regulatory_requests));
+
+       reset_regdomains();
+
+       cfg80211_world_regdom = rd;
+       cfg80211_regdomain = rd;
+}
+
+bool is_world_regdom(const char *alpha2)
 {
        if (!alpha2)
                return false;
@@ -60,7 +221,7 @@ bool is_world_regdom(char *alpha2)
        return false;
 }
 
-static bool is_alpha2_set(char *alpha2)
+static bool is_alpha2_set(const char *alpha2)
 {
        if (!alpha2)
                return false;
@@ -77,7 +238,7 @@ static bool is_alpha_upper(char letter)
        return false;
 }
 
-static bool is_unknown_alpha2(char *alpha2)
+static bool is_unknown_alpha2(const char *alpha2)
 {
        if (!alpha2)
                return false;
@@ -88,7 +249,7 @@ static bool is_unknown_alpha2(char *alpha2)
        return false;
 }
 
-static bool is_an_alpha2(char *alpha2)
+static bool is_an_alpha2(const char *alpha2)
 {
        if (!alpha2)
                return false;
@@ -97,7 +258,7 @@ static bool is_an_alpha2(char *alpha2)
        return false;
 }
 
-static bool alpha2_equal(char *alpha2_x, char *alpha2_y)
+static bool alpha2_equal(const char *alpha2_x, const char *alpha2_y)
 {
        if (!alpha2_x || !alpha2_y)
                return false;
@@ -107,7 +268,7 @@ static bool alpha2_equal(char *alpha2_x, char *alpha2_y)
        return false;
 }
 
-static bool regdom_changed(char *alpha2)
+static bool regdom_changed(const char *alpha2)
 {
        if (!cfg80211_regdomain)
                return true;
@@ -130,12 +291,8 @@ static int call_crda(const char *alpha2)
                printk(KERN_INFO "cfg80211: Calling CRDA for country: %c%c\n",
                        alpha2[0], alpha2[1]);
        else
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-               return -EINVAL;
-#else
                printk(KERN_INFO "cfg80211: Calling CRDA to update world "
                        "regulatory domain\n");
-#endif
 
        country_env[8] = alpha2[0];
        country_env[9] = alpha2[1];
@@ -238,7 +395,7 @@ static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
        }
 }
 
-static bool __reg_is_valid_request(char *alpha2,
+static bool __reg_is_valid_request(const char *alpha2,
        struct regulatory_request **request)
 {
        struct regulatory_request *req;
@@ -254,16 +411,16 @@ static bool __reg_is_valid_request(char *alpha2,
 }
 
 /* Used by nl80211 before kmalloc'ing our regulatory domain */
-bool reg_is_valid_request(char *alpha2)
+bool reg_is_valid_request(const char *alpha2)
 {
        struct regulatory_request *request = NULL;
        return  __reg_is_valid_request(alpha2, &request);
 }
 
 /* Sanity check on a regulatory rule */
-static bool is_valid_reg_rule(struct ieee80211_reg_rule *rule)
+static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
 {
-       struct ieee80211_freq_range *freq_range = &rule->freq_range;
+       const struct ieee80211_freq_range *freq_range = &rule->freq_range;
        u32 freq_diff;
 
        if (freq_range->start_freq_khz == 0 || freq_range->end_freq_khz == 0)
@@ -280,9 +437,9 @@ static bool is_valid_reg_rule(struct ieee80211_reg_rule *rule)
        return true;
 }
 
-static bool is_valid_rd(struct ieee80211_regdomain *rd)
+static bool is_valid_rd(const struct ieee80211_regdomain *rd)
 {
-       struct ieee80211_reg_rule *reg_rule = NULL;
+       const struct ieee80211_reg_rule *reg_rule = NULL;
        unsigned int i;
 
        if (!rd->n_reg_rules)
@@ -494,12 +651,12 @@ unlock_and_exit:
 EXPORT_SYMBOL(regulatory_hint);
 
 
-static void print_rd_rules(struct ieee80211_regdomain *rd)
+static void print_rd_rules(const struct ieee80211_regdomain *rd)
 {
        unsigned int i;
-       struct ieee80211_reg_rule *reg_rule = NULL;
-       struct ieee80211_freq_range *freq_range = NULL;
-       struct ieee80211_power_rule *power_rule = NULL;
+       const struct ieee80211_reg_rule *reg_rule = NULL;
+       const struct ieee80211_freq_range *freq_range = NULL;
+       const struct ieee80211_power_rule *power_rule = NULL;
 
        printk(KERN_INFO "\t(start_freq - end_freq @ bandwidth), "
                "(max_antenna_gain, max_eirp)\n");
@@ -529,7 +686,7 @@ static void print_rd_rules(struct ieee80211_regdomain *rd)
        }
 }
 
-static void print_regdomain(struct ieee80211_regdomain *rd)
+static void print_regdomain(const struct ieee80211_regdomain *rd)
 {
 
        if (is_world_regdom(rd->alpha2))
@@ -548,85 +705,25 @@ static void print_regdomain(struct ieee80211_regdomain *rd)
        print_rd_rules(rd);
 }
 
-void print_regdomain_info(struct ieee80211_regdomain *rd)
+void print_regdomain_info(const struct ieee80211_regdomain *rd)
 {
        printk(KERN_INFO "cfg80211: Regulatory domain: %c%c\n",
                rd->alpha2[0], rd->alpha2[1]);
        print_rd_rules(rd);
 }
 
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-
-static bool is_old_static_regdom(struct ieee80211_regdomain *rd)
-{
-       if (rd == &us_regdom || rd == &jp_regdom || rd == &eu_regdom)
-               return true;
-       return false;
-}
-
-/* The old crap never deals with a world regulatory domain, it only
- * deals with the static regulatory domain passed and if possible
- * an updated "US" or "JP" regulatory domain. We do however store the
- * old static regulatory domain in cfg80211_world_regdom for convenience
- * of use here */
-static void reset_regdomains_static(void)
-{
-       if (!is_old_static_regdom(cfg80211_regdomain))
-               kfree(cfg80211_regdomain);
-       /* This is setting the regdom to the old static regdom */
-       cfg80211_regdomain =
-               (struct ieee80211_regdomain *) cfg80211_world_regdom;
-}
-#else
-static void reset_regdomains(void)
-{
-       if (cfg80211_world_regdom && cfg80211_world_regdom != &world_regdom) {
-               if (cfg80211_world_regdom == cfg80211_regdomain) {
-                       kfree(cfg80211_regdomain);
-               } else {
-                       kfree(cfg80211_world_regdom);
-                       kfree(cfg80211_regdomain);
-               }
-       } else if (cfg80211_regdomain && cfg80211_regdomain != &world_regdom)
-               kfree(cfg80211_regdomain);
-
-       cfg80211_world_regdom = (struct ieee80211_regdomain *) &world_regdom;
-       cfg80211_regdomain = NULL;
-}
-
-/* Dynamic world regulatory domain requested by the wireless
- * core upon initialization */
-static void update_world_regdomain(struct ieee80211_regdomain *rd)
-{
-       BUG_ON(list_empty(&regulatory_requests));
-
-       reset_regdomains();
-
-       cfg80211_world_regdom = rd;
-       cfg80211_regdomain = rd;
-}
-#endif
-
-static int __set_regdom(struct ieee80211_regdomain *rd)
+static int __set_regdom(const struct ieee80211_regdomain *rd)
 {
        struct regulatory_request *request = NULL;
 
        /* Some basic sanity checks first */
 
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-       /* We ignore the world regdom with the old static regdomains setup
-        * as there is no point to it with satic regulatory definitions :(
-        * Don't worry this shit will be removed soon... */
-       if (is_world_regdom(rd->alpha2))
-               return -EINVAL;
-#else
        if (is_world_regdom(rd->alpha2)) {
                if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
                        return -EINVAL;
                update_world_regdomain(rd);
                return 0;
        }
-#endif
 
        if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) &&
                        !is_unknown_alpha2(rd->alpha2))
@@ -635,15 +732,10 @@ static int __set_regdom(struct ieee80211_regdomain *rd)
        if (list_empty(&regulatory_requests))
                return -EINVAL;
 
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-       /* Static "US" and "JP" will be overridden, but just once */
+       /* allow overriding the static definitions if CRDA is present */
        if (!is_old_static_regdom(cfg80211_regdomain) &&
-                       !regdom_changed(rd->alpha2))
-               return -EINVAL;
-#else
-       if (!regdom_changed(rd->alpha2))
+           !regdom_changed(rd->alpha2))
                return -EINVAL;
-#endif
 
        /* Now lets set the regulatory domain, update all driver channels
         * and finally inform them of what we have done, in case they want
@@ -653,11 +745,7 @@ static int __set_regdom(struct ieee80211_regdomain *rd)
        if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
                return -EINVAL;
 
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-       reset_regdomains_static();
-#else
        reset_regdomains();
-#endif
 
        /* Country IE parsing coming soon */
        switch (request->initiator) {
@@ -689,7 +777,7 @@ static int __set_regdom(struct ieee80211_regdomain *rd)
  * multiple drivers can be ironed out later. Caller must've already
  * kmalloc'd the rd structure. If this calls fails you should kfree()
  * the passed rd. Caller must hold cfg80211_drv_mutex */
-int set_regdom(struct ieee80211_regdomain *rd)
+int set_regdom(const struct ieee80211_regdomain *rd)
 {
        struct regulatory_request *this_request = NULL, *prev_request = NULL;
        int r;
@@ -735,25 +823,50 @@ int set_regdom(struct ieee80211_regdomain *rd)
 
 int regulatory_init(void)
 {
+       int err;
+
        reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0);
        if (IS_ERR(reg_pdev))
                return PTR_ERR(reg_pdev);
+
+#ifdef CONFIG_WIRELESS_OLD_REGULATORY
+       cfg80211_regdomain = static_regdom(ieee80211_regdom);
+
+       printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
+       print_regdomain_info(cfg80211_regdomain);
+       /* The old code still requests for a new regdomain and if
+        * you have CRDA you get it updated, otherwise you get
+        * stuck with the static values. We ignore "EU" code as
+        * that is not a valid ISO / IEC 3166 alpha2 */
+       if (ieee80211_regdom[0] != 'E' && ieee80211_regdom[1] != 'U')
+               err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE,
+                                       ieee80211_regdom, NULL);
+#else
+       cfg80211_regdomain = cfg80211_world_regdom;
+
+       err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", NULL);
+       if (err)
+               printk(KERN_ERR "cfg80211: calling CRDA failed - "
+                      "unable to update world regulatory domain, "
+                      "using static definition\n");
+#endif
+
        return 0;
 }
 
 void regulatory_exit(void)
 {
        struct regulatory_request *req, *req_tmp;
+
        mutex_lock(&cfg80211_drv_mutex);
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-       reset_regdomains_static();
-#else
+
        reset_regdomains();
-#endif
+
        list_for_each_entry_safe(req, req_tmp, &regulatory_requests, list) {
                list_del(&req->list);
                kfree(req);
        }
        platform_device_unregister(reg_pdev);
+
        mutex_unlock(&cfg80211_drv_mutex);
 }
index d75fd02329724ce47af8a15dc7e0c35979392ece..a33362872f3cc3820ae46c32c010400242912bc0 100644 (file)
@@ -1,44 +1,13 @@
 #ifndef __NET_WIRELESS_REG_H
 #define __NET_WIRELESS_REG_H
 
-extern const struct ieee80211_regdomain world_regdom;
-#ifdef CONFIG_WIRELESS_OLD_REGULATORY
-extern const struct ieee80211_regdomain us_regdom;
-extern const struct ieee80211_regdomain jp_regdom;
-extern const struct ieee80211_regdomain eu_regdom;
-#endif
-
-extern struct ieee80211_regdomain *cfg80211_regdomain;
-extern struct ieee80211_regdomain *cfg80211_world_regdom;
-extern struct list_head regulatory_requests;
-
-struct regdom_last_setby {
-       struct wiphy *wiphy;
-       u8 initiator;
-};
-
-/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
-struct regulatory_request {
-       struct list_head list;
-       struct wiphy *wiphy;
-       int granted;
-       enum reg_set_by initiator;
-       char alpha2[2];
-};
-
-bool is_world_regdom(char *alpha2);
-bool reg_is_valid_request(char *alpha2);
-
-int set_regdom(struct ieee80211_regdomain *rd);
-int __regulatory_hint_alpha2(struct wiphy *wiphy, enum reg_set_by set_by,
-                     const char *alpha2);
+extern struct mutex cfg80211_reg_mutex;
+bool is_world_regdom(const char *alpha2);
+bool reg_is_valid_request(const char *alpha2);
 
 int regulatory_init(void);
 void regulatory_exit(void);
 
-void print_regdomain_info(struct ieee80211_regdomain *);
-
-/* If a char is A-Z */
-#define IS_ALPHA(letter) (letter >= 65 && letter <= 90)
+int set_regdom(const struct ieee80211_regdomain *rd);
 
 #endif  /* __NET_WIRELESS_REG_H */
index ac25b4c0e982ee7d5089f7cf5c41d6d73c39ab51..dc50f1e71f76f86487ebded9991cb20bc4e46ef9 100644 (file)
@@ -27,10 +27,14 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
                - skb_headroom(skb);
        int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
 
-       if (nhead > 0 || ntail > 0)
-               return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
-
-       return 0;
+       if (nhead <= 0) {
+               if (ntail <= 0)
+                       return 0;
+               nhead = 0;
+       } else if (ntail < 0)
+               ntail = 0;
+
+       return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
 }
 
 static int xfrm_output_one(struct sk_buff *skb, int err)
index ef9ccbc387525f1ead4493d5d4297b554cff9657..832b47c1de8065c8626d5ce40d39b2d313f7199c 100644 (file)
@@ -46,7 +46,7 @@ EXPORT_SYMBOL(xfrm_cfg_mutex);
 
 static DEFINE_RWLOCK(xfrm_policy_lock);
 
-static struct list_head xfrm_policy_bytype[XFRM_POLICY_TYPE_MAX];
+static struct list_head xfrm_policy_all;
 unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
 EXPORT_SYMBOL(xfrm_policy_count);
 
@@ -164,7 +164,7 @@ static void xfrm_policy_timer(unsigned long data)
 
        read_lock(&xp->lock);
 
-       if (xp->dead)
+       if (xp->walk.dead)
                goto out;
 
        dir = xfrm_policy_id2dir(xp->index);
@@ -236,7 +236,7 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp)
        policy = kzalloc(sizeof(struct xfrm_policy), gfp);
 
        if (policy) {
-               INIT_LIST_HEAD(&policy->bytype);
+               INIT_LIST_HEAD(&policy->walk.all);
                INIT_HLIST_NODE(&policy->bydst);
                INIT_HLIST_NODE(&policy->byidx);
                rwlock_init(&policy->lock);
@@ -252,17 +252,13 @@ EXPORT_SYMBOL(xfrm_policy_alloc);
 
 void xfrm_policy_destroy(struct xfrm_policy *policy)
 {
-       BUG_ON(!policy->dead);
+       BUG_ON(!policy->walk.dead);
 
        BUG_ON(policy->bundles);
 
        if (del_timer(&policy->timer))
                BUG();
 
-       write_lock_bh(&xfrm_policy_lock);
-       list_del(&policy->bytype);
-       write_unlock_bh(&xfrm_policy_lock);
-
        security_xfrm_policy_free(policy->security);
        kfree(policy);
 }
@@ -310,8 +306,8 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
        int dead;
 
        write_lock_bh(&policy->lock);
-       dead = policy->dead;
-       policy->dead = 1;
+       dead = policy->walk.dead;
+       policy->walk.dead = 1;
        write_unlock_bh(&policy->lock);
 
        if (unlikely(dead)) {
@@ -609,6 +605,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
        if (delpol) {
                hlist_del(&delpol->bydst);
                hlist_del(&delpol->byidx);
+               list_del(&delpol->walk.all);
                xfrm_policy_count[dir]--;
        }
        policy->index = delpol ? delpol->index : xfrm_gen_index(policy->type, dir);
@@ -617,7 +614,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
        policy->curlft.use_time = 0;
        if (!mod_timer(&policy->timer, jiffies + HZ))
                xfrm_pol_hold(policy);
-       list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]);
+       list_add(&policy->walk.all, &xfrm_policy_all);
        write_unlock_bh(&xfrm_policy_lock);
 
        if (delpol)
@@ -684,6 +681,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
                                }
                                hlist_del(&pol->bydst);
                                hlist_del(&pol->byidx);
+                               list_del(&pol->walk.all);
                                xfrm_policy_count[dir]--;
                        }
                        ret = pol;
@@ -727,6 +725,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
                                }
                                hlist_del(&pol->bydst);
                                hlist_del(&pol->byidx);
+                               list_del(&pol->walk.all);
                                xfrm_policy_count[dir]--;
                        }
                        ret = pol;
@@ -840,6 +839,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
                                        continue;
                                hlist_del(&pol->bydst);
                                hlist_del(&pol->byidx);
+                               list_del(&pol->walk.all);
                                write_unlock_bh(&xfrm_policy_lock);
 
                                xfrm_audit_policy_delete(pol, 1,
@@ -867,60 +867,68 @@ int xfrm_policy_walk(struct xfrm_policy_walk *walk,
                     int (*func)(struct xfrm_policy *, int, int, void*),
                     void *data)
 {
-       struct xfrm_policy *old, *pol, *last = NULL;
+       struct xfrm_policy *pol;
+       struct xfrm_policy_walk_entry *x;
        int error = 0;
 
        if (walk->type >= XFRM_POLICY_TYPE_MAX &&
            walk->type != XFRM_POLICY_TYPE_ANY)
                return -EINVAL;
 
-       if (walk->policy == NULL && walk->count != 0)
+       if (list_empty(&walk->walk.all) && walk->seq != 0)
                return 0;
 
-       old = pol = walk->policy;
-       walk->policy = NULL;
-       read_lock_bh(&xfrm_policy_lock);
-
-       for (; walk->cur_type < XFRM_POLICY_TYPE_MAX; walk->cur_type++) {
-               if (walk->type != walk->cur_type &&
-                   walk->type != XFRM_POLICY_TYPE_ANY)
+       write_lock_bh(&xfrm_policy_lock);
+       if (list_empty(&walk->walk.all))
+               x = list_first_entry(&xfrm_policy_all, struct xfrm_policy_walk_entry, all);
+       else
+               x = list_entry(&walk->walk.all, struct xfrm_policy_walk_entry, all);
+       list_for_each_entry_from(x, &xfrm_policy_all, all) {
+               if (x->dead)
                        continue;
-
-               if (pol == NULL) {
-                       pol = list_first_entry(&xfrm_policy_bytype[walk->cur_type],
-                                              struct xfrm_policy, bytype);
-               }
-               list_for_each_entry_from(pol, &xfrm_policy_bytype[walk->cur_type], bytype) {
-                       if (pol->dead)
-                               continue;
-                       if (last) {
-                               error = func(last, xfrm_policy_id2dir(last->index),
-                                            walk->count, data);
-                               if (error) {
-                                       xfrm_pol_hold(last);
-                                       walk->policy = last;
-                                       goto out;
-                               }
-                       }
-                       last = pol;
-                       walk->count++;
+               pol = container_of(x, struct xfrm_policy, walk);
+               if (walk->type != XFRM_POLICY_TYPE_ANY &&
+                   walk->type != pol->type)
+                       continue;
+               error = func(pol, xfrm_policy_id2dir(pol->index),
+                            walk->seq, data);
+               if (error) {
+                       list_move_tail(&walk->walk.all, &x->all);
+                       goto out;
                }
-               pol = NULL;
+               walk->seq++;
        }
-       if (walk->count == 0) {
+       if (walk->seq == 0) {
                error = -ENOENT;
                goto out;
        }
-       if (last)
-               error = func(last, xfrm_policy_id2dir(last->index), 0, data);
+       list_del_init(&walk->walk.all);
 out:
-       read_unlock_bh(&xfrm_policy_lock);
-       if (old != NULL)
-               xfrm_pol_put(old);
+       write_unlock_bh(&xfrm_policy_lock);
        return error;
 }
 EXPORT_SYMBOL(xfrm_policy_walk);
 
+void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type)
+{
+       INIT_LIST_HEAD(&walk->walk.all);
+       walk->walk.dead = 1;
+       walk->type = type;
+       walk->seq = 0;
+}
+EXPORT_SYMBOL(xfrm_policy_walk_init);
+
+void xfrm_policy_walk_done(struct xfrm_policy_walk *walk)
+{
+       if (list_empty(&walk->walk.all))
+               return;
+
+       write_lock_bh(&xfrm_policy_lock);
+       list_del(&walk->walk.all);
+       write_unlock_bh(&xfrm_policy_lock);
+}
+EXPORT_SYMBOL(xfrm_policy_walk_done);
+
 /*
  * Find policy to apply to this flow.
  *
@@ -1077,7 +1085,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
        struct hlist_head *chain = policy_hash_bysel(&pol->selector,
                                                     pol->family, dir);
 
-       list_add_tail(&pol->bytype, &xfrm_policy_bytype[pol->type]);
+       list_add(&pol->walk.all, &xfrm_policy_all);
        hlist_add_head(&pol->bydst, chain);
        hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index));
        xfrm_policy_count[dir]++;
@@ -1095,6 +1103,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
 
        hlist_del(&pol->bydst);
        hlist_del(&pol->byidx);
+       list_del(&pol->walk.all);
        xfrm_policy_count[dir]--;
 
        return pol;
@@ -1720,7 +1729,7 @@ restart:
 
                for (pi = 0; pi < npols; pi++) {
                        read_lock_bh(&pols[pi]->lock);
-                       pol_dead |= pols[pi]->dead;
+                       pol_dead |= pols[pi]->walk.dead;
                        read_unlock_bh(&pols[pi]->lock);
                }
 
@@ -2415,9 +2424,7 @@ static void __init xfrm_policy_init(void)
                        panic("XFRM: failed to allocate bydst hash\n");
        }
 
-       for (dir = 0; dir < XFRM_POLICY_TYPE_MAX; dir++)
-               INIT_LIST_HEAD(&xfrm_policy_bytype[dir]);
-
+       INIT_LIST_HEAD(&xfrm_policy_all);
        INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task);
        register_netdevice_notifier(&xfrm_dev_notifier);
 }
@@ -2601,7 +2608,7 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
        int i, j, n = 0;
 
        write_lock_bh(&pol->lock);
-       if (unlikely(pol->dead)) {
+       if (unlikely(pol->walk.dead)) {
                /* target policy has been deleted */
                write_unlock_bh(&pol->lock);
                return -ENOENT;
@@ -2672,7 +2679,8 @@ static int xfrm_migrate_check(struct xfrm_migrate *m, int num_migrate)
 }
 
 int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
-                struct xfrm_migrate *m, int num_migrate)
+                struct xfrm_migrate *m, int num_migrate,
+                struct xfrm_kmaddress *k)
 {
        int i, err, nx_cur = 0, nx_new = 0;
        struct xfrm_policy *pol = NULL;
@@ -2716,7 +2724,7 @@ int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
        }
 
        /* Stage 5 - announce */
-       km_migrate(sel, dir, type, m, num_migrate);
+       km_migrate(sel, dir, type, m, num_migrate, k);
 
        xfrm_pol_put(pol);
 
index abbe2702c4007e42e5ad7b53986adb5776328867..508337f97249d421e524013cdd83c86b6cbbf210 100644 (file)
@@ -59,11 +59,6 @@ static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
 static unsigned int xfrm_state_num;
 static unsigned int xfrm_state_genid;
 
-/* Counter indicating ongoing walk, protected by xfrm_state_lock. */
-static unsigned long xfrm_state_walk_ongoing;
-/* Counter indicating walk completion, protected by xfrm_cfg_mutex. */
-static unsigned long xfrm_state_walk_completed;
-
 static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
 static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
 
@@ -196,8 +191,7 @@ static DEFINE_RWLOCK(xfrm_state_afinfo_lock);
 static struct xfrm_state_afinfo *xfrm_state_afinfo[NPROTO];
 
 static struct work_struct xfrm_state_gc_work;
-static LIST_HEAD(xfrm_state_gc_leftovers);
-static LIST_HEAD(xfrm_state_gc_list);
+static HLIST_HEAD(xfrm_state_gc_list);
 static DEFINE_SPINLOCK(xfrm_state_gc_lock);
 
 int __xfrm_state_delete(struct xfrm_state *x);
@@ -409,23 +403,16 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
 
 static void xfrm_state_gc_task(struct work_struct *data)
 {
-       struct xfrm_state *x, *tmp;
-       unsigned long completed;
+       struct xfrm_state *x;
+       struct hlist_node *entry, *tmp;
+       struct hlist_head gc_list;
 
-       mutex_lock(&xfrm_cfg_mutex);
        spin_lock_bh(&xfrm_state_gc_lock);
-       list_splice_tail_init(&xfrm_state_gc_list, &xfrm_state_gc_leftovers);
+       hlist_move_list(&xfrm_state_gc_list, &gc_list);
        spin_unlock_bh(&xfrm_state_gc_lock);
 
-       completed = xfrm_state_walk_completed;
-       mutex_unlock(&xfrm_cfg_mutex);
-
-       list_for_each_entry_safe(x, tmp, &xfrm_state_gc_leftovers, gclist) {
-               if ((long)(x->lastused - completed) > 0)
-                       break;
-               list_del(&x->gclist);
+       hlist_for_each_entry_safe(x, entry, tmp, &gc_list, gclist)
                xfrm_state_gc_destroy(x);
-       }
 
        wake_up(&km_waitq);
 }
@@ -526,7 +513,7 @@ struct xfrm_state *xfrm_state_alloc(void)
        if (x) {
                atomic_set(&x->refcnt, 1);
                atomic_set(&x->tunnel_users, 0);
-               INIT_LIST_HEAD(&x->all);
+               INIT_LIST_HEAD(&x->km.all);
                INIT_HLIST_NODE(&x->bydst);
                INIT_HLIST_NODE(&x->bysrc);
                INIT_HLIST_NODE(&x->byspi);
@@ -553,7 +540,7 @@ void __xfrm_state_destroy(struct xfrm_state *x)
        WARN_ON(x->km.state != XFRM_STATE_DEAD);
 
        spin_lock_bh(&xfrm_state_gc_lock);
-       list_add_tail(&x->gclist, &xfrm_state_gc_list);
+       hlist_add_head(&x->gclist, &xfrm_state_gc_list);
        spin_unlock_bh(&xfrm_state_gc_lock);
        schedule_work(&xfrm_state_gc_work);
 }
@@ -566,8 +553,7 @@ int __xfrm_state_delete(struct xfrm_state *x)
        if (x->km.state != XFRM_STATE_DEAD) {
                x->km.state = XFRM_STATE_DEAD;
                spin_lock(&xfrm_state_lock);
-               x->lastused = xfrm_state_walk_ongoing;
-               list_del_rcu(&x->all);
+               list_del(&x->km.all);
                hlist_del(&x->bydst);
                hlist_del(&x->bysrc);
                if (x->id.spi)
@@ -868,7 +854,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
 
                if (km_query(x, tmpl, pol) == 0) {
                        x->km.state = XFRM_STATE_ACQ;
-                       list_add_tail(&x->all, &xfrm_state_all);
+                       list_add(&x->km.all, &xfrm_state_all);
                        hlist_add_head(&x->bydst, xfrm_state_bydst+h);
                        h = xfrm_src_hash(daddr, saddr, family);
                        hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -937,7 +923,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
        x->genid = ++xfrm_state_genid;
 
-       list_add_tail(&x->all, &xfrm_state_all);
+       list_add(&x->km.all, &xfrm_state_all);
 
        h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
                          x->props.reqid, x->props.family);
@@ -1066,7 +1052,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
                xfrm_state_hold(x);
                x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
                add_timer(&x->timer);
-               list_add_tail(&x->all, &xfrm_state_all);
+               list_add(&x->km.all, &xfrm_state_all);
                hlist_add_head(&x->bydst, xfrm_state_bydst+h);
                h = xfrm_src_hash(daddr, saddr, family);
                hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -1563,61 +1549,59 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,
                    int (*func)(struct xfrm_state *, int, void*),
                    void *data)
 {
-       struct xfrm_state *old, *x, *last = NULL;
+       struct xfrm_state *state;
+       struct xfrm_state_walk *x;
        int err = 0;
 
-       if (walk->state == NULL && walk->count != 0)
+       if (walk->seq != 0 && list_empty(&walk->all))
                return 0;
 
-       old = x = walk->state;
-       walk->state = NULL;
        spin_lock_bh(&xfrm_state_lock);
-       if (x == NULL)
-               x = list_first_entry(&xfrm_state_all, struct xfrm_state, all);
+       if (list_empty(&walk->all))
+               x = list_first_entry(&xfrm_state_all, struct xfrm_state_walk, all);
+       else
+               x = list_entry(&walk->all, struct xfrm_state_walk, all);
        list_for_each_entry_from(x, &xfrm_state_all, all) {
-               if (x->km.state == XFRM_STATE_DEAD)
+               if (x->state == XFRM_STATE_DEAD)
                        continue;
-               if (!xfrm_id_proto_match(x->id.proto, walk->proto))
+               state = container_of(x, struct xfrm_state, km);
+               if (!xfrm_id_proto_match(state->id.proto, walk->proto))
                        continue;
-               if (last) {
-                       err = func(last, walk->count, data);
-                       if (err) {
-                               xfrm_state_hold(last);
-                               walk->state = last;
-                               xfrm_state_walk_ongoing++;
-                               goto out;
-                       }
+               err = func(state, walk->seq, data);
+               if (err) {
+                       list_move_tail(&walk->all, &x->all);
+                       goto out;
                }
-               last = x;
-               walk->count++;
+               walk->seq++;
        }
-       if (walk->count == 0) {
+       if (walk->seq == 0) {
                err = -ENOENT;
                goto out;
        }
-       if (last)
-               err = func(last, 0, data);
+       list_del_init(&walk->all);
 out:
        spin_unlock_bh(&xfrm_state_lock);
-       if (old != NULL) {
-               xfrm_state_put(old);
-               xfrm_state_walk_completed++;
-               if (!list_empty(&xfrm_state_gc_leftovers))
-                       schedule_work(&xfrm_state_gc_work);
-       }
        return err;
 }
 EXPORT_SYMBOL(xfrm_state_walk);
 
+void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
+{
+       INIT_LIST_HEAD(&walk->all);
+       walk->proto = proto;
+       walk->state = XFRM_STATE_DEAD;
+       walk->seq = 0;
+}
+EXPORT_SYMBOL(xfrm_state_walk_init);
+
 void xfrm_state_walk_done(struct xfrm_state_walk *walk)
 {
-       if (walk->state != NULL) {
-               xfrm_state_put(walk->state);
-               walk->state = NULL;
-               xfrm_state_walk_completed++;
-               if (!list_empty(&xfrm_state_gc_leftovers))
-                       schedule_work(&xfrm_state_gc_work);
-       }
+       if (list_empty(&walk->all))
+               return;
+
+       spin_lock_bh(&xfrm_state_lock);
+       list_del(&walk->all);
+       spin_lock_bh(&xfrm_state_lock);
 }
 EXPORT_SYMBOL(xfrm_state_walk_done);
 
@@ -1830,7 +1814,8 @@ EXPORT_SYMBOL(km_policy_expired);
 
 #ifdef CONFIG_XFRM_MIGRATE
 int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
-              struct xfrm_migrate *m, int num_migrate)
+              struct xfrm_migrate *m, int num_migrate,
+              struct xfrm_kmaddress *k)
 {
        int err = -EINVAL;
        int ret;
@@ -1839,7 +1824,7 @@ int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
        read_lock(&xfrm_km_lock);
        list_for_each_entry(km, &xfrm_km_list, list) {
                if (km->migrate) {
-                       ret = km->migrate(sel, dir, type, m, num_migrate);
+                       ret = km->migrate(sel, dir, type, m, num_migrate, k);
                        if (!ret)
                                err = ret;
                }
index 04c41504f84c44b8b84d8be9b6cc602d568d3ce1..4a8a1abb59ee8ae7c611d85def77d363ca96380e 100644 (file)
@@ -1102,7 +1102,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
        return xp;
  error:
        *errp = err;
-       xp->dead = 1;
+       xp->walk.dead = 1;
        xfrm_policy_destroy(xp);
        return NULL;
 }
@@ -1595,7 +1595,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
                return -ENOENT;
 
        read_lock(&xp->lock);
-       if (xp->dead) {
+       if (xp->walk.dead) {
                read_unlock(&xp->lock);
                goto out;
        }
@@ -1710,12 +1710,23 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 #ifdef CONFIG_XFRM_MIGRATE
 static int copy_from_user_migrate(struct xfrm_migrate *ma,
+                                 struct xfrm_kmaddress *k,
                                  struct nlattr **attrs, int *num)
 {
        struct nlattr *rt = attrs[XFRMA_MIGRATE];
        struct xfrm_user_migrate *um;
        int i, num_migrate;
 
+       if (k != NULL) {
+               struct xfrm_user_kmaddress *uk;
+
+               uk = nla_data(attrs[XFRMA_KMADDRESS]);
+               memcpy(&k->local, &uk->local, sizeof(k->local));
+               memcpy(&k->remote, &uk->remote, sizeof(k->remote));
+               k->family = uk->family;
+               k->reserved = uk->reserved;
+       }
+
        um = nla_data(rt);
        num_migrate = nla_len(rt) / sizeof(*um);
 
@@ -1745,6 +1756,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
 {
        struct xfrm_userpolicy_id *pi = nlmsg_data(nlh);
        struct xfrm_migrate m[XFRM_MAX_DEPTH];
+       struct xfrm_kmaddress km, *kmp;
        u8 type;
        int err;
        int n = 0;
@@ -1752,19 +1764,20 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
        if (attrs[XFRMA_MIGRATE] == NULL)
                return -EINVAL;
 
+       kmp = attrs[XFRMA_KMADDRESS] ? &km : NULL;
+
        err = copy_from_user_policy_type(&type, attrs);
        if (err)
                return err;
 
-       err = copy_from_user_migrate((struct xfrm_migrate *)m,
-                                    attrs, &n);
+       err = copy_from_user_migrate((struct xfrm_migrate *)m, kmp, attrs, &n);
        if (err)
                return err;
 
        if (!n)
                return 0;
 
-       xfrm_migrate(&pi->sel, pi->dir, type, m, n);
+       xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp);
 
        return 0;
 }
@@ -1795,16 +1808,30 @@ static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb)
        return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um);
 }
 
-static inline size_t xfrm_migrate_msgsize(int num_migrate)
+static int copy_to_user_kmaddress(struct xfrm_kmaddress *k, struct sk_buff *skb)
+{
+       struct xfrm_user_kmaddress uk;
+
+       memset(&uk, 0, sizeof(uk));
+       uk.family = k->family;
+       uk.reserved = k->reserved;
+       memcpy(&uk.local, &k->local, sizeof(uk.local));
+       memcpy(&uk.remote, &k->local, sizeof(uk.remote));
+
+       return nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk);
+}
+
+static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma)
 {
        return NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id))
-              + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)
-              + userpolicy_type_attrsize();
+             + (with_kma ? nla_total_size(sizeof(struct xfrm_kmaddress)) : 0)
+             + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)
+             + userpolicy_type_attrsize();
 }
 
 static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
-                        int num_migrate, struct xfrm_selector *sel,
-                        u8 dir, u8 type)
+                        int num_migrate, struct xfrm_kmaddress *k,
+                        struct xfrm_selector *sel, u8 dir, u8 type)
 {
        struct xfrm_migrate *mp;
        struct xfrm_userpolicy_id *pol_id;
@@ -1821,6 +1848,9 @@ static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
        memcpy(&pol_id->sel, sel, sizeof(pol_id->sel));
        pol_id->dir = dir;
 
+       if (k != NULL && (copy_to_user_kmaddress(k, skb) < 0))
+                       goto nlmsg_failure;
+
        if (copy_to_user_policy_type(type, skb) < 0)
                goto nlmsg_failure;
 
@@ -1836,23 +1866,25 @@ nlmsg_failure:
 }
 
 static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
-                            struct xfrm_migrate *m, int num_migrate)
+                            struct xfrm_migrate *m, int num_migrate,
+                            struct xfrm_kmaddress *k)
 {
        struct sk_buff *skb;
 
-       skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate), GFP_ATOMIC);
+       skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC);
        if (skb == NULL)
                return -ENOMEM;
 
        /* build migrate */
-       if (build_migrate(skb, m, num_migrate, sel, dir, type) < 0)
+       if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0)
                BUG();
 
        return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC);
 }
 #else
 static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
-                            struct xfrm_migrate *m, int num_migrate)
+                            struct xfrm_migrate *m, int num_migrate,
+                            struct xfrm_kmaddress *k)
 {
        return -ENOPROTOOPT;
 }
@@ -1901,6 +1933,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
        [XFRMA_COADDR]          = { .len = sizeof(xfrm_address_t) },
        [XFRMA_POLICY_TYPE]     = { .len = sizeof(struct xfrm_userpolicy_type)},
        [XFRMA_MIGRATE]         = { .len = sizeof(struct xfrm_user_migrate) },
+       [XFRMA_KMADDRESS]       = { .len = sizeof(struct xfrm_user_kmaddress) },
 };
 
 static struct xfrm_link {
index 36b5eedcdc7518d9dc734078c2287e16cca9f4d0..3e1057f885c6a2496e981e6180611aa6878cede0 100644 (file)
@@ -32,6 +32,7 @@ char *defconfig_file;
 
 static int indent = 1;
 static int valid_stdin = 1;
+static int sync_kconfig;
 static int conf_cnt;
 static char line[128];
 static struct menu *rootEntry;
@@ -65,7 +66,7 @@ static void strip(char *str)
 
 static void check_stdin(void)
 {
-       if (!valid_stdin && input_mode == ask_silent) {
+       if (!valid_stdin) {
                printf(_("aborted!\n\n"));
                printf(_("Console input/output is redirected. "));
                printf(_("Run 'make oldconfig' to update configuration.\n\n"));
@@ -427,43 +428,6 @@ static void check_conf(struct menu *menu)
                check_conf(child);
 }
 
-static void conf_do_update(void)
-{
-       /* Update until a loop caused no more changes */
-       do {
-               conf_cnt = 0;
-               check_conf(&rootmenu);
-       } while (conf_cnt);
-}
-
-static int conf_silent_update(void)
-{
-       const char *name;
-
-       if (conf_get_changed()) {
-               name = getenv("KCONFIG_NOSILENTUPDATE");
-               if (name && *name) {
-                       fprintf(stderr,
-                       _("\n*** Kernel configuration requires explicit update.\n\n"));
-                       return 1;
-               }
-               conf_do_update();
-       }
-       return 0;
-}
-
-static int conf_update(void)
-{
-       rootEntry = &rootmenu;
-       conf(&rootmenu);
-       if (input_mode == ask_all) {
-               input_mode = ask_silent;
-               valid_stdin = 1;
-       }
-       conf_do_update();
-       return 0;
-}
-
 int main(int ac, char **av)
 {
        int opt;
@@ -477,11 +441,11 @@ int main(int ac, char **av)
        while ((opt = getopt(ac, av, "osdD:nmyrh")) != -1) {
                switch (opt) {
                case 'o':
-                       input_mode = ask_new;
+                       input_mode = ask_silent;
                        break;
                case 's':
                        input_mode = ask_silent;
-                       valid_stdin = isatty(0) && isatty(1) && isatty(2);
+                       sync_kconfig = 1;
                        break;
                case 'd':
                        input_mode = set_default;
@@ -519,6 +483,19 @@ int main(int ac, char **av)
        name = av[optind];
        conf_parse(name);
        //zconfdump(stdout);
+       if (sync_kconfig) {
+               if (stat(".config", &tmpstat)) {
+                       fprintf(stderr, _("***\n"
+                               "*** You have not yet configured your kernel!\n"
+                               "*** (missing kernel .config file)\n"
+                               "***\n"
+                               "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
+                               "*** \"make menuconfig\" or \"make xconfig\").\n"
+                               "***\n"));
+                       exit(1);
+               }
+       }
+
        switch (input_mode) {
        case set_default:
                if (!defconfig_file)
@@ -531,16 +508,6 @@ int main(int ac, char **av)
                }
                break;
        case ask_silent:
-               if (stat(".config", &tmpstat)) {
-                       printf(_("***\n"
-                               "*** You have not yet configured your kernel!\n"
-                               "*** (missing kernel .config file)\n"
-                               "***\n"
-                               "*** Please run some configurator (e.g. \"make oldconfig\" or\n"
-                               "*** \"make menuconfig\" or \"make xconfig\").\n"
-                               "***\n"));
-                       exit(1);
-               }
        case ask_all:
        case ask_new:
                conf_read(NULL);
@@ -569,6 +536,19 @@ int main(int ac, char **av)
        default:
                break;
        }
+
+       if (sync_kconfig) {
+               if (conf_get_changed()) {
+                       name = getenv("KCONFIG_NOSILENTUPDATE");
+                       if (name && *name) {
+                               fprintf(stderr,
+                                       _("\n*** Kernel configuration requires explicit update.\n\n"));
+                               return 1;
+                       }
+               }
+               valid_stdin = isatty(0) && isatty(1) && isatty(2);
+       }
+
        switch (input_mode) {
        case set_no:
                conf_set_all_new_symbols(def_no);
@@ -585,27 +565,38 @@ int main(int ac, char **av)
        case set_default:
                conf_set_all_new_symbols(def_default);
                break;
-       case ask_silent:
        case ask_new:
-               if (conf_silent_update())
-                       exit(1);
-               break;
        case ask_all:
-               if (conf_update())
-                       exit(1);
+               rootEntry = &rootmenu;
+               conf(&rootmenu);
+               input_mode = ask_silent;
+               /* fall through */
+       case ask_silent:
+               /* Update until a loop caused no more changes */
+               do {
+                       conf_cnt = 0;
+                       check_conf(&rootmenu);
+               } while (conf_cnt);
                break;
        }
 
-       if (conf_write(NULL)) {
-               fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
-               exit(1);
-       }
-       /* ask_silent is used during the build so we shall update autoconf.
-        * All other commands are only used to generate a config.
-        */
-       if (input_mode == ask_silent && conf_write_autoconf()) {
-               fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
-               return 1;
+       if (sync_kconfig) {
+               /* silentoldconfig is used during the build so we shall update autoconf.
+                * All other commands are only used to generate a config.
+                */
+               if (conf_get_changed() && conf_write(NULL)) {
+                       fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
+                       exit(1);
+               }
+               if (conf_write_autoconf()) {
+                       fprintf(stderr, _("\n*** Error during update of the kernel configuration.\n\n"));
+                       return 1;
+               }
+       } else {
+               if (conf_write(NULL)) {
+                       fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
+                       exit(1);
+               }
        }
        return 0;
 }
index df6a188b993002ae7d2ca82cb12e8b853aefcb42..b91cf241a539ceaadbf603374d45b3c012a24e41 100644 (file)
@@ -222,8 +222,10 @@ load:
                                continue;
                        if (def == S_DEF_USER) {
                                sym = sym_find(line + 9);
-                               if (!sym)
+                               if (!sym) {
+                                       sym_add_change_count(1);
                                        break;
+                               }
                        } else {
                                sym = sym_lookup(line + 9, 0);
                                if (sym->type == S_UNKNOWN)
@@ -259,8 +261,10 @@ load:
                        }
                        if (def == S_DEF_USER) {
                                sym = sym_find(line + 7);
-                               if (!sym)
+                               if (!sym) {
+                                       sym_add_change_count(1);
                                        break;
+                               }
                        } else {
                                sym = sym_lookup(line + 7, 0);
                                if (sym->type == S_UNKNOWN)
index ff787e6ff8edcbef0edc7fbfaef7f3d088f930a0..44ee94d2ab761ba46b1f8f155009d78dbac2daad 100755 (executable)
@@ -781,6 +781,7 @@ sub output_struct_xml(%) {
     print " <refsect1>\n";
     print "  <title>Members</title>\n";
 
+    if ($#{$args{'parameterlist'}} >= 0) {
     print "  <variablelist>\n";
     foreach $parameter (@{$args{'parameterlist'}}) {
       ($parameter =~ /^#/) && next;
@@ -798,6 +799,9 @@ sub output_struct_xml(%) {
       print "    </varlistentry>\n";
     }
     print "  </variablelist>\n";
+    } else {
+       print " <para>\n  None\n </para>\n";
+    }
     print " </refsect1>\n";
 
     output_section_xml(@_);
index 9dd9bc73fe1d6ab8b568fa1ce865650f52bae72f..ece25c718e95e8f78c5a71b01df6e01e80519908 100644 (file)
@@ -781,7 +781,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
                return -ENODEV;
 
        card = pcm->card;
-       down_read(&card->controls_rwsem);
+       read_lock(&card->ctl_files_rwlock);
        list_for_each_entry(kctl, &card->ctl_files, list) {
                if (kctl->pid == current->pid) {
                        prefer_subdevice = kctl->prefer_pcm_subdevice;
@@ -789,7 +789,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
                                break;
                }
        }
-       up_read(&card->controls_rwsem);
+       read_unlock(&card->ctl_files_rwlock);
 
        switch (stream) {
        case SNDRV_PCM_STREAM_PLAYBACK:
index c49b9d9e303c76d6495943b5b99fb02eff710e1f..c487025d345777d56ba228918bbc95eb9564cd05 100644 (file)
@@ -1546,16 +1546,10 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
        card = substream->pcm->card;
 
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
-           runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
+           runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED ||
+           runtime->status->state == SNDRV_PCM_STATE_SUSPENDED)
                return -EBADFD;
 
-       snd_power_lock(card);
-       if (runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
-               result = snd_power_wait(card, SNDRV_CTL_POWER_D0);
-               if (result < 0)
-                       goto _unlock;
-       }
-
        snd_pcm_stream_lock_irq(substream);
        /* resume pause */
        if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
@@ -1564,8 +1558,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
        snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
        /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
        snd_pcm_stream_unlock_irq(substream);
- _unlock:
-       snd_power_unlock(card);
+
        return result;
 }
 
index f7ea7287c59cd7edfcf75bc5795efce07d512d79..b917a9f981c7a276b3fbff94deece3f4ab8aa2f4 100644 (file)
@@ -418,7 +418,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
        mutex_lock(&rmidi->open_mutex);
        while (1) {
                subdevice = -1;
-               down_read(&card->controls_rwsem);
+               read_lock(&card->ctl_files_rwlock);
                list_for_each_entry(kctl, &card->ctl_files, list) {
                        if (kctl->pid == current->pid) {
                                subdevice = kctl->prefer_rawmidi_subdevice;
@@ -426,7 +426,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
                                        break;
                        }
                }
-               up_read(&card->controls_rwsem);
+               read_unlock(&card->ctl_files_rwlock);
                err = snd_rawmidi_kernel_open(rmidi->card, rmidi->device,
                                              subdevice, fflags, rawmidi_file);
                if (err >= 0)
index 435f1daf177c39e767cd4a7b6999f6d81d9847dc..c83584f989a9bea6223e611acce0ea37f8f2b51c 100644 (file)
@@ -434,7 +434,8 @@ static int at32_pcm_suspend(struct platform_device *pdev,
        params = prtd->params;
 
        /* Disable the PDC and save the PDC registers */
-       ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
+       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
+                  params->mask->pdc_disable);
 
        prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
        prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
@@ -464,7 +465,7 @@ static int at32_pcm_resume(struct platform_device *pdev,
        ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
        ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
 
-       ssc_writex(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
+       ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
        return 0;
 }
 #else /* CONFIG_PM */
index 9deb8c74fdfd3f1c07f5b1eaf518d4b8f145b5d6..d68650de39bcb93bef72b7cba61feb4bb13816ee 100644 (file)
@@ -490,34 +490,7 @@ static int cs4270_mute(struct snd_soc_dai *dai, int mute)
 
 #endif
 
-static int cs4270_i2c_probe(struct i2c_adapter *adap, int addr, int kind);
-
-/*
- * Notify the driver that a new I2C bus has been found.
- *
- * This function is called for each I2C bus in the system.  The function
- * then asks the I2C subsystem to probe that bus at the addresses on which
- * our device (the CS4270) could exist.  If a device is found at one of
- * those addresses, then our probe function (cs4270_i2c_probe) is called.
- */
-static int cs4270_i2c_attach(struct i2c_adapter *adapter)
-{
-       return i2c_probe(adapter, &addr_data, cs4270_i2c_probe);
-}
-
-static int cs4270_i2c_detach(struct i2c_client *client)
-{
-       struct snd_soc_codec *codec = i2c_get_clientdata(client);
-
-       i2c_detach_client(client);
-       codec->control_data = NULL;
-
-       kfree(codec->reg_cache);
-       codec->reg_cache = NULL;
-
-       kfree(client);
-       return 0;
-}
+static int cs4270_i2c_probe(struct i2c_client *, const struct i2c_device_id *);
 
 /* A list of non-DAPM controls that the CS4270 supports */
 static const struct snd_kcontrol_new cs4270_snd_controls[] = {
@@ -525,14 +498,19 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
                CS4270_VOLA, CS4270_VOLB, 0, 0xFF, 1)
 };
 
+static const struct i2c_device_id cs4270_id[] = {
+       {"cs4270", 0},
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, cs4270_id);
+
 static struct i2c_driver cs4270_i2c_driver = {
        .driver = {
                .name = "CS4270 I2C",
                .owner = THIS_MODULE,
        },
-       .id =             I2C_DRIVERID_CS4270,
-       .attach_adapter = cs4270_i2c_attach,
-       .detach_client =  cs4270_i2c_detach,
+       .id_table = cs4270_id,
+       .probe = cs4270_i2c_probe,
 };
 
 /*
@@ -561,11 +539,11 @@ static struct snd_soc_device *cs4270_socdev;
  * Note: snd_soc_new_pcms() must be called before this function can be called,
  * because of snd_ctl_add().
  */
-static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
+static int cs4270_i2c_probe(struct i2c_client *i2c_client,
+       const struct i2c_device_id *id)
 {
        struct snd_soc_device *socdev = cs4270_socdev;
        struct snd_soc_codec *codec = socdev->codec;
-       struct i2c_client *i2c_client = NULL;
        int i;
        int ret = 0;
 
@@ -578,12 +556,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
 
        /* Note: codec_dai->codec is NULL here */
 
-       i2c_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (!i2c_client) {
-               printk(KERN_ERR "cs4270: could not allocate I2C client\n");
-               return -ENOMEM;
-       }
-
        codec->reg_cache = kzalloc(CS4270_NUMREGS, GFP_KERNEL);
        if (!codec->reg_cache) {
                printk(KERN_ERR "cs4270: could not allocate register cache\n");
@@ -591,13 +563,6 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                goto error;
        }
 
-       i2c_set_clientdata(i2c_client, codec);
-       strcpy(i2c_client->name, "CS4270");
-
-       i2c_client->driver = &cs4270_i2c_driver;
-       i2c_client->adapter = adapter;
-       i2c_client->addr = addr;
-
        /* Verify that we have a CS4270 */
 
        ret = i2c_smbus_read_byte_data(i2c_client, CS4270_CHIPID);
@@ -612,18 +577,10 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                goto error;
        }
 
-       printk(KERN_INFO "cs4270: found device at I2C address %X\n", addr);
+       printk(KERN_INFO "cs4270: found device at I2C address %X\n",
+               i2c_client->addr);
        printk(KERN_INFO "cs4270: hardware revision %X\n", ret & 0xF);
 
-       /* Tell the I2C layer a new client has arrived */
-
-       ret = i2c_attach_client(i2c_client);
-       if (ret) {
-               printk(KERN_ERR "cs4270: could not attach codec, "
-                       "I2C address %x, error code %i\n", addr, ret);
-               goto error;
-       }
-
        codec->control_data = i2c_client;
        codec->read = cs4270_read_reg_cache;
        codec->write = cs4270_i2c_write;
@@ -648,20 +605,17 @@ static int cs4270_i2c_probe(struct i2c_adapter *adapter, int addr, int kind)
                        goto error;
        }
 
+       i2c_set_clientdata(i2c_client, codec);
+
        return 0;
 
 error:
-       if (codec->control_data) {
-               i2c_detach_client(i2c_client);
-               codec->control_data = NULL;
-       }
+       codec->control_data = NULL;
 
        kfree(codec->reg_cache);
        codec->reg_cache = NULL;
        codec->reg_cache_size = 0;
 
-       kfree(i2c_client);
-
        return ret;
 }